springboot 网页授权微信登录

需要的工具:

微信公众号(可以申请,但做开发的,可以申请测试号,申请详细不多说了)

服务器

编辑器(随意,不做推荐)

微信公众号开发文档(地址

-------------------------官方文档解读(只说我读到的信息)

!!!!!完成基本配置后才能进行一下工作,配置信息在这。(稍后补上)

你要完成网页授权,并获取用户信息要完成一下3步骤。

-1-用户授权并获取code

-2-使用code换取access_token

-3-使用access_token获取用户信息

--------------------用户授权并获取code

参数说明
appid=APPID(公众号唯一标识)
redirect_uri=REDIRECT_URI(授权后重定向的回调链接地址)
response_type=code(返回类型,无需更改)
scope=SCOPE(snsapi_base ,不弹出授权页面,直接跳转,只能获取用户openid),snsapi_userinfo 弹出授权页面,可通过openid拿到昵称、性别、所在地。)
state=STATE(重定向后会带上state参数,开发者可以填写任意参数值)
#wechat_redirect(无需更改)

地址实例(虽是测试号,但我还是隐藏部分信息)红色字体需要根据实际更改。
https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxe5809c42e6c00d22&redirect_uri=http://dingcanphp.applinzi.com/getUserInfo.php&response_type=code&scope=snsapi_userinfo&state=1#wechat_redirect

返回结果(code的值,不一定是显示在浏览器界面上的,具体看你的redirect_uri中的文件)
061h4k8Z1G7AhY0025bZ1nbh8Z1h4k8Q

-----------------使用code换取access_token

参数说明
appid=APPID(公众号唯一标识)
secret=SECRET(公众号的appsecret)
code=CODE(第一步获取的code参数)
grant_type=authorization_code(无需更改)


地址实例(虽是测试号,但我还是隐藏部分信息)红色字体需要根据实际更改。
https://api.weixin.qq.com/sns/oauth2/access_token?appid=wxe5809c42e6c00d22&secret=5444ba1b31666f6052e9c703f906368b&code=061h4k8Z1G7AhY0025bZ1nbh8Z1h4k8Q&grant_type=authorization_code

返回结果(json格式数据)

{
"access_token": "e1nYJFpZuehfQH1buzHFZLb7onqs_wT1cudSdy9HRlnaMXFtFpRMNFOA0euK6UxPcItrSNbAQVcXDdthbLJYX0MdH1p7-tkZSKuGqBCxVc0",
"expires_in": 7200,
"refresh_token": "0iVsXn4O1rBCASbO7hx8VNVUVFM1RP2Q4xS0giegd4jlIsJYOjTJNZ0b4Dsh_xcoB02ZZ3bt0WH0a47LvjIEPjWUnESJCZyl6EtY_xYZdVs",
"openid": "o47Fa0mp9SRTf3eiKmqWm69BjG_8",
"scope": "snsapi_userinfo"
}

结果解释
access_token 网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同
expires_in access_token接口调用凭证超时时间,单位(秒)
refresh_token 用户刷新access_token
openid 用户唯一标识,请注意,在未关注公众号时,用户访问公众号的网页,也会产生一个用户和公众号唯一的OpenID
scope 用户授权的作用域,使用逗号(,)分隔

-----------------使用access_token获取用户信息

参数说明
access_token=ACCESS_TOKEN(第2步获取的access_token参数,此access_token与基础支持的access_token不同)
openid=OPENID(第2步获取的openid参数)
langlang=zh_CN 返回国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语

地址实例(虽是测试号,但我还是隐藏部分信息)红色字体需要根据实际更改。
https://api.weixin.qq.com/sns/userinfo?access_token=e1nYJFpZuehfQH1buzHFZLb7onqs_wT1cudSdy9HRlnaMXFtFpRMNFOA0euK6UxPcItrSNbAQVcXDdthbLJYX0MdH1p7-tkZSKuGqBCxVc0&openid=o47Fa0mp9SRTf3eiKmqWm69BjG_8&lang=zh_CN

返回结果(json格式数据)

{
"openid": "o47Fa0mp9SRTf3eiKmqWm69BjG_8",
"nickname": "齐齐",
"sex": 0,
"language": "zh_CN",
"city": "Shaoxing",
"province": "Zhejiang",
"country": "CN",
"headimgurl": "http://wx.qlogo.cn/mmhead/Q3auHgzwzM6kqfcibzzVc8MDGBch53mIgJjWrbKSwkBnzcsWBOMOGlg/0",
"privilege": []
}

结果解释
openid 用户的唯一标识
nickname 用户昵称
sex 用户的性别,值为1时是男性,值为2时是女性,值为0时是未知
province 用户个人资料填写的省份
city 普通用户个人资料填写的城市
country 国家,如中国为CN
headimgurl 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空
privilege 用户特权信息,json 数组,如微信沃卡用户为(chinaunicom)

**********************代码实现****************

1.添加POM

<!-- 微信公众号 -->
<dependency>
    <groupId>com.github.liyiorg</groupId>
    <artifactId>weixin-popular</artifactId>
    <version>2.8.17</version>
</dependency>

2.引导用户打开授权页面:(weixin.html)

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>微信登录</title>
</head>
<body>

</body>
<script>
    window.location.href="https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxfc649223af094yc4&redirect_uri=http://xxxx.cn/AR/weixin/getAccess_Token&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect";
</script>
</html>

PS:redirect_uri需要去微信公众号里面配置

3.接收code,通过code换取网页授权web_access_token和用户信息

	@RequestMapping("/getAccess_Token")
	public void listVote(@RequestParam(name = "code", required = false) String code,
						 @RequestParam(name = "state") String state) {


		System.out.println("-----------------------------收到请求,请求数据为:" + code + "-----------------------" + state);

		//通过code换取网页授权web_access_token
		if (code != null || !(code.equals(""))) {

			String APPID = weiXinConfig.getAppid();
			String SECRET = weiXinConfig.getSecret();
			String CODE = code;
			String WebAccessToken = "";
			String openId = "";


			//替换字符串,获得请求URL
			String token = UserInfoUtil.getWebAccess(APPID, SECRET, CODE);
			System.out.println("----------------------------token为:" + token);
			//通过https方式请求获得web_access_token
			String response = HttpsUtil.httpsRequestToString(token, "GET", null);
			JSONObject jsonObject = JSON.parseObject(response);
			System.out.println("jsonObject------" + jsonObject);
			if (null != jsonObject) {
				try {

					WebAccessToken = jsonObject.getString("access_token");
					openId = jsonObject.getString("openid");
					System.out.println("获取access_token成功-------------------------" + WebAccessToken + "----------------" + openId);

					//-----------------------拉取用户信息...替换字符串,获得请求URL
					String userMessage = UserInfoUtil.getUserMessage(WebAccessToken, openId);
					System.out.println(" userMessage===" + userMessage);
					//通过https方式请求获得用户信息响应
					String userMessageResponse = HttpsUtil.httpsRequestToString(userMessage, "GET", null);

					JSONObject userMessageJsonObject = JSON.parseObject(userMessageResponse);

					System.out.println("userMessagejsonObject------" + userMessageJsonObject);

					if (userMessageJsonObject != null) {
						try {
							//用户昵称
							String nickName = userMessageJsonObject.getString("nickname");
							//用户性别
							String sex = userMessageJsonObject.getString("sex");
							sex = (sex.equals("1")) ? "男" : "女";
							//用户唯一标识
							String openid = userMessageJsonObject.getString("openid");

							System.out.println("用户昵称------------------------" + nickName);
							System.out.println("用户性别------------------------" + sex);
							System.out.println("用户的唯一标识-------------------" + openid);

							//获取成果,存入数据库


						} catch (JSONException e) {
							System.out.println("获取userName失败");
						}
					}


				} catch (JSONException e) {
					WebAccessToken = null;// 获取code失败
					System.out.println("获取WebAccessToken失败");
				}
			}
		}
	}

4.appid和secret我是在application.yml里面配置的

###################  微信配置  ###################
wechat:
  appid: wxfc649223af094bc6
  secret: 78dc0e47ae8fc33c6036eeee66518acc

5.新建一个WeiXinConfig

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix="wechat")
public class WeiXinConfig {
    private String appid;
    private String secret;

    public String getAppid() {
        return appid;
    }

    public void setAppid(String appid) {
        this.appid = appid;
    }

    public String getSecret() {
        return secret;
    }

    public void setSecret(String secret) {
        this.secret = secret;
    }
}

6.UserInfoUtil工具类

public class UserInfoUtil {
    //获取code的请求地址
    public static String Get_Code = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=STAT#wechat_redirect";
    //替换字符串
    public static String getCode(String APPID, String REDIRECT_URI,String SCOPE) {
        return String.format(Get_Code,APPID,REDIRECT_URI,SCOPE);
    }

    //获取Web_access_tokenhttps的请求地址
    public static String Web_access_tokenhttps = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code";
    //替换字符串
    public static String getWebAccess(String APPID, String SECRET,String CODE) {
        return String.format(Web_access_tokenhttps, APPID, SECRET,CODE);
    }

    //拉取用户信息的请求地址
    public static String User_Message = "https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN";
    //替换字符串
    public static String getUserMessage(String access_token, String openid) {
        return String.format(User_Message, access_token,openid);
    }

    public static void main(String[] args) {
        String REDIRECT_URI = "http://xxxx.cn/test";
        String SCOPE = "snsapi_userinfo";
        //appId
        String appId = "wxfc649223afxxx";

        String getCodeUrl = getCode(appId, REDIRECT_URI, SCOPE);
        System.out.println("getCodeUrl:" + getCodeUrl);
    }
}

7.HttpsUtil类

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.URL;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;



public class HttpsUtil {

    /**
     * 以https方式发送请求并将请求响应内容以String方式返回
     *
     * @param path   请求路径
     * @param method 请求方法
     * @param body   请求数据体
     * @return 请求响应内容转换成字符串信息
     */
    public static String httpsRequestToString(String path, String method, String body) {
        if (path == null || method == null) {
            return null;
        }

        String response = null;
        InputStream inputStream = null;
        InputStreamReader inputStreamReader = null;
        BufferedReader bufferedReader = null;
        HttpsURLConnection conn = null;
        try {
            //创建SSLConrext对象,并使用我们指定的信任管理器初始化
            TrustManager[] tm = {new JEEWeiXinX509TrustManager()};
            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
            sslContext.init(null, tm, new java.security.SecureRandom());

            //从上述对象中的到SSLSocketFactory
            SSLSocketFactory ssf = sslContext.getSocketFactory();

            System.out.println(path);

            URL url = new URL(path);
            conn = (HttpsURLConnection) url.openConnection();
            conn.setSSLSocketFactory(ssf);

            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setUseCaches(false);

            //设置请求方式(git|post)
            conn.setRequestMethod(method);

            //有数据提交时
            if (null != body) {
                OutputStream outputStream = conn.getOutputStream();
                outputStream.write(body.getBytes("UTF-8"));
                outputStream.close();
            }

            //将返回的输入流转换成字符串
            inputStream = conn.getInputStream();
            inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
            bufferedReader = new BufferedReader(inputStreamReader);
            String str = null;
            StringBuffer buffer = new StringBuffer();
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }

            response = buffer.toString();
        } catch (Exception e) {

        } finally {
            if (conn != null) {
                conn.disconnect();
            }
            try {
                bufferedReader.close();
                inputStreamReader.close();
                inputStream.close();
            } catch (IOException execption) {

            }
        }
        return response;
    }


}

class JEEWeiXinX509TrustManager implements X509TrustManager {
    public void checkClientTrusted(X509Certificate[] chain, String authType)
            throws CertificateException {
    }

    public void checkServerTrusted(X509Certificate[] chain, String authType)
            throws CertificateException {
    }

    public X509Certificate[] getAcceptedIssuers() {
        return null;
    }
}

最后直接打开weixin.html就行了

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

儿时可乖了

混口饭吃,大佬们,赏点吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值