微信公众号授权登录、获取用户信息(openid)

配置微信公众号开发环境就不赘述了。

进入正题。。。。。

首先,先理清楚微信登录的两种实现途径(这里我们先演示一种)1.微信开放平台实现,2.微信公众号(微信公众平台)实现。

因为微信登录不同与QQ登录,微信登录只提供扫码方式登录,并不像其他应用登录让用户输入用户名,密码。对用户并不友好。所以出现微信公众号登录,让用户授权。


实现方式也是两种:

1.没有自己的帐号体系,直接拉去微信用户信息来进行网站登录(我们所展示的信息全部来自于微信)

2.有自己的账号体系,授权成功后需要绑定自己的账号,绑定成功后,下次登录所展示的信息是自己的账号体系下面的用户信息

下面开始

1.微信公众号,推荐使用测试账号(拥有所有权限)

2.看微信授权登录的文档

3.代码部分了(尽可能的加上了注释)

工具类

package com.wlw.util;
import java.io.IOException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

import net.sf.json.JSONObject;

/**
 * 
 * 工具类
 * 用来根据接口地址进行网络请求
 * @author wlw
 *
 */
public class AuthUtil {
	public static final String APP_ID = "****************";     //填写自己的APPID
	public static final String APP_SECRET = "**************";   //填写自己的APPSECRET
    public static JSONObject doGetJson(String url) throws Exception, IOException {
		JSONObject jsonObject=null;
		//初始化httpClient
		DefaultHttpClient client=new DefaultHttpClient();
		//用Get方式进行提交
		HttpGet httpGet=new HttpGet(url);
		//发送请求
		HttpResponse response= client.execute(httpGet);
    	//获取数据
		HttpEntity entity=response.getEntity();
		//格式转换
		if (entity!=null) {
			String result=EntityUtils.toString(entity,"UTF-8");
			jsonObject=JSONObject.fromObject(result);
		}
		//释放链接
		httpGet.releaseConnection();
		return jsonObject;
    }
	   
}

组装入口地址

package com.wlw.servlet;
import java.io.IOException;
import java.net.URLEncoder;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.wlw.util.AuthUtil;;

/**
 * 组装入口地址
 * 进行授权页面的授权地址组装
 * @author wlw
 *
 */
@WebServlet("/wxLogin")
public class LoginServiet extends HttpServlet{

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		//回调地址(必须在公网进行访问)
		String backUrl="http://w.ngrok.xiaomiqiu.cn/we/callBack";
		String url="https://open.weixin.qq.com/connect/oauth2/authorize?appid="+AuthUtil.APP_ID
				+ "&redirect_uri="+URLEncoder.encode(backUrl)
				+ "&response_type=code"
				+ "&scope=snsapi_userinfo"
				+ "&state=STATE#wechat_redirect";
		//重定向
		resp.sendRedirect(url);
	}
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		super.doPost(req, resp);
	}
}

到这里很多人不明白回调地址到底是个啥玩意,

回调地址是当我们用户同意授权后,程序会进行对回调地址的访问。所以回调地址必须在公网上能够进行访问的。

还有个重点是scope(授权的作用域)。两个参数snsapi_base、snsapi_userinfo。。使用base作用域,不会弹出会话框,直接跳过,直接进入到回调地址,运行之后的程序,它默认是授权的(只能获取到openid)。。而userinfo,会弹出会话框,让用户选择,确认,才会进入回调地址(获取openID,通过openID拿到其他信息),用户取消则不进入回调地址。

微信公众号的bug之一就出现了,如果先使用userinfo作用域,再去使用base作用域,居然也能获取到用户的其他信息。至于为什么就要去问微信的开发大佬了。

回调地址的处理

package com.wlw.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.wlw.util.AuthUtil;
import net.sf.json.JSONObject;

/**
 * 回调地址
 * 
 * @author wlw
 *
 */
@WebServlet("/callBack")
public class CallBackServlet extends HttpServlet {
	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		/**
		 * 3.获取code
		 */
		String code=req.getParameter("code");
	String url="https://api.weixin.qq.com/sns/oauth2/access_token?appid="+AuthUtil.APP_ID
			+ "&secret="+AuthUtil.APP_SECRET
			+ "&code="+code
			+ "&grant_type=authorization_code";
	JSONObject jsonObject;
	try {
		jsonObject = AuthUtil.doGetJson(url);
		String openid=jsonObject.getString("openid");
		String token=jsonObject.getString("access_token");
		/**
		 * 4.拉取用户信息
		 */
		String infoUrl="https://api.weixin.qq.com/sns/userinfo?access_token="+token
				+ "&openid="+openid
				+ "&lang=zh_CN";
		JSONObject userInfo=AuthUtil.doGetJson(infoUrl);
		System.out.println(userInfo);
		
		//使用微信用户信息直接登录,无需注册和绑定
		req.setAttribute("info", userInfo);
		req.getRequestDispatcher("/index1.jsp").forward(req, resp);
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		super.doPost(req, resp);
	}

}

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body style="font-size:40px;text-align:center;">
    <a href="/we/wxLogin">微信公众 版权登录</a>
</body>
</html>

index1.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body style="font-size:40px;text-align:center;">
   <div>登录成功!</div>
   <div>用户昵称: ${info.nickname}</div>
   <div>用户头像: <img style="vertical-align: top;" width="100" height="" alt="" src="${info.headimgurl}"></div>
   <div>登录成功!</div>
</body>
</html>

截图配置信息


写自己的域名。。。不要带http

参考图2 截图配置信息  这里应该填   1afa5dc0.ngrok.io


然后在浏览器输入地址访问,会显示需要在微信端进行访问.


只需将地址换成二维码,扫描即可。如何换成二维码呢,我建议使用谷歌浏览器,方便,直接在地址栏右击,就会有二维码。扫一扫即可。


微信扫描,点击授权,登录进去页面显示


后台获取到的数据


原理就是两个Servlet和两个JSP页面。一个是用户进入的登录页面,只不过不用输入用户名密码,直接授权登录。另外一个页面为展示用户的数据。两个Servlet配合JSP页面处理后台。

这一次演示的是没有自己帐号体系,不需要绑定,直接登录。

帐号体系的授权登录自行百度。

猜你喜欢

转载自blog.csdn.net/qq_42547698/article/details/80931178