第三方登录之微信登录流程和代码

微信登录:
在第三方注册一个账号;访问地址,获取code,再通过code获取at,在通过at调用地址获取资源.
0:域名的本地映射,在微信开放平台注册一个账号,进行开发者的认证.
1,请求code
参数说明
参数 是否必须 说明
appid 是 应用唯一标识
redirect_uri 是 请使用urlEncode对链接进行处理
response_type 是 填code
scope 是 应用授权作用域,拥有多个作用域用逗号(,)分隔,网页应用目前仅填写snsapi_login即
state 否 用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验
返回说明
用户允许授权后,将会重定向到redirect_uri的网址上,并且带上code和state参数
redirect_uri?code=CODE&state=STATE
若用户禁止授权,则重定向后不会带上code参数,仅会带上state参数
redirect_uri?state=STATE
.第二步:通过code获取access_token
通过code获取access_token
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
参数说明
参数 是否必须 说明
appid 是 应用唯一标识,在微信开放平台提交应用审核通过后获得
secret 是 应用密钥AppSecret,在微信开放平台提交应用审核通过后获得
code 是 填写第一步获取的code参数
grant_type 是 填authorization_code
返回说明
正确的返回:
{
“access_token”:“ACCESS_TOKEN”,
“expires_in”:7200,
“refresh_token”:“REFRESH_TOKEN”,
“openid”:“OPENID”,
“scope”:“SCOPE”,
“unionid”: “o6_bmasdasdsad6_2sgVt7hMZOPfL”
}
参数说明
参数 说明
access_token 接口调用凭证
expires_in access_token接口调用凭证超时时间,单位(秒)
refresh_token 用户刷新access_token
openid 授权用户唯一标识
scope 用户授权的作用域,使用逗号(,)分隔
unionid 当且仅当该网站应用已获得该用户的userinfo授权时,才会出现该字段。
错误返回样例:
{“errcode”:40029,“errmsg”:“invalid code”}
刷新access_token有效期
access_token是调用授权关系接口的调用凭证,由于access_token有效期(目前为2个小时)较短,当access_token超时后,可以使用refresh_token进行刷新,access_token刷新结果有两种:

  1. 若access_token已超时,那么进行refresh_token会获取一个新的access_token,新的超时时间;
  2. 若access_token未超时,那么进行refresh_token不会改变access_token,但超时时间会刷新,相当于续期access_token。
    refresh_token拥有较长的有效期(30天),当refresh_token失效的后,需要用户重新授权。
    请求方法
    获取第一步的code后,请求以下链接进行refresh_token:
    https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN
    参数说明
    参数 是否必须 说明
    appid 是 应用唯一标识
    grant_type 是 填refresh_token
    refresh_token 是 填写通过access_token获取到的refresh_token参数
    返回说明
    正确的返回:
    {
    “access_token”:“ACCESS_TOKEN”,
    “expires_in”:7200,
    “refresh_token”:“REFRESH_TOKEN”,
    “openid”:“OPENID”,
    “scope”:“SCOPE”
    }
    参数说明
    参数 说明
    access_token 接口调用凭证
    expires_in access_token接口调用凭证超时时间,单位(秒)
    refresh_token 用户刷新access_token
    openid 授权用户唯一标识
    scope 用户授权的作用域,使用逗号(,)分隔
    错误返回样例:
    {“errcode”:40030,“errmsg”:“invalid refresh_token”}
    注意:
    1、Appsecret 是应用接口使用密钥,泄漏后将可能导致应用数据泄漏、应用的用户数据泄漏等高风险后果;存储在客户端,极有可能被恶意窃取(如反编译获取Appsecret);
    2、access_token 为用户授权第三方应用发起接口调用的凭证(相当于用户登录态),存储在客户端,可能出现恶意获取access_token 后导致的用户数据泄漏、用户微信相关接口功能被恶意发起等行为;
    3、refresh_token 为用户授权第三方应用的长效凭证,仅用于刷新access_token,但泄漏后相当于access_token 泄漏,风险同上。

建议将secret、用户数据(如access_token)放在App云端服务器,由云端中转接口调用请求。
.第三步:通过access_token调用接口
获取access_token后,进行接口调用,有以下前提:

  1. access_token有效且未超时;
  2. 微信用户已授权给第三方应用帐号相应接口作用域(scope)。
    对于接口作用域(scope),能调用的接口有以下:
    授权作用域(scope) 接口 接口说明
    snsapi_base /sns/oauth2/access_token 通过code换取access_token、refresh_token和已授权scope
    snsapi_base /sns/oauth2/refresh_token 刷新或续期access_token使用
    snsapi_base /sns/auth 检查access_token有效性
    snsapi_userinfo /sns/userinfo 获取用户个人信息
    第四步:授权后接口调用(UnionID)
    3.4.1.通过code获取access_token
    接口说明
    通过code获取access_token的接口。
    请求说明
    http请求方式: GET
    https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
    参数说明
    参数 是否必须 说明
    appid 是 应用唯一标识,在微信开放平台提交应用审核通过后获得
    secret 是 应用密钥AppSecret,在微信开放平台提交应用审核通过后获得
    code 是 填写第一步获取的code参数
    grant_type 是 填authorization_code
    返回说明
    正确的返回:
    {
    “access_token”:“ACCESS_TOKEN”,
    “expires_in”:7200,
    “refresh_token”:“REFRESH_TOKEN”,“openid”:“OPENID”,
    “scope”:“SCOPE”
    }
    参数 说明
    access_token 接口调用凭证
    expires_in access_token接口调用凭证超时时间,单位(秒)
    refresh_token 用户刷新access_token
    openid 授权用户唯一标识
    scope 用户授权的作用域,使用逗号(,)分隔
    错误返回样例:
    {
    “errcode”:40029,“errmsg”:“invalid code”

以下是实现代码:
配置hosts文件:
127.0.0.1 bugtracker.itsource.cn
192.168.1.103 bugtracker.itsource.cn
位置:C:\Windows\System32\drivers\etc
1.导入maven包

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.47</version>
</dependency>
<dependency>
   <groupId>org.apache.httpcomponents</groupId>
   <artifactId>httpclient</artifactId>
     <version>4.5.2</version>
</dependency>

2.工具类的封装

public class HttpClientUtil {
    // http://bugtracker.itsource.cn/wechat/callback?code=222&state=99
    // http://bugtracker.itsource.cn/wechat/callback    code=222&state=99
    public  static String doGet(String uri){
        //1:创建一个HttpClient的实例
        CloseableHttpClient httpclient = HttpClients.createDefault();
        //2:创建一个get请求实例
        HttpGet httpGet = new HttpGet(uri);
        //请求的响应:
        CloseableHttpResponse response1=null;
        try {
            //3:使用HttpClient的实例执行get请求
            response1= httpclient.execute(httpGet);
            //http请求的状态:404 500 200
            System.out.println(response1.getStatusLine());
            int statusCode = response1.getStatusLine().getStatusCode();
            if(statusCode==200){
              //请求成功:
                HttpEntity entity1 = response1.getEntity();
                String result = EntityUtils.toString(entity1, "utf-8");
                System.out.println(result);
                return result;
            }else{
                //请求失败:自己做自己的业务逻辑
            }

        }catch (Exception ex){
            ex.printStackTrace();
        }
        return null;
    }
    
  *3.常量封装*


     public class WxConstants {
    public final static String APPID = "wxd853562a0548a7d0";
    //用户授权后微信的回调域名
    public final static String CALLBACK="http://bugtracker.itsource.cn";
    public final static String SCOPE = "snsapi_login";
    public final static String APPSECRET = "4a5d5615f93f24bdba2ba8534642dbb6";
    //微信上获取code的地址
    public final static String CODEURL = "https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect";
    //微信上获取at的地址
    public final static String ACCESSTOKEURL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
    //微信上获取用户信息的地址
    public final static String USERINFOURL = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID";

}

4.核心代码

@Controller
@RequestMapping("/wechat")
public class WeChatController {


    @RequestMapping("/login")
    public String index(){
        return "wxlogin";
    }
    @RequestMapping("/callback")
    public String callback(String code, String state, Model model, HttpServletRequest req){
 String atUrl =  WeChatConstants.ACCESS_TOKEN.replace("APPID",WeChatConstants.APPID)
                .replace("SECRET",WeChatConstants.SECRET)
                .replace("CODE",code);
        String atJsonStr = HttpClientUtil.doGet(atUrl);
        System.out.println("atJsonStr:"+atJsonStr);
        JSONObject jsonObject = (JSONObject)JSON.parse(atJsonStr);
        String access_token = String.valueOf(jsonObject.get("access_token"));
        String open_id = String.valueOf(jsonObject.get("openid"));
        System.out.println("access_token:"+access_token);
        System.out.println("open_id:"+open_id);
        String userInfoUrl = WeChatConstants.USER_INFO.replace("ACCESS_TOKEN", access_token).replace("OPENID", open_id);
        String userInfo = HttpClientUtil.doGet(userInfoUrl);
        JSONObject userJson = (JSONObject)JSON.parse(userInfo);
        System.out.println(userJson);
        //完成绑定操作
        model.addAttribute("userInfo", userInfo);
        return "main";
    }
}

5.创建login页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<a href="/wechat/login1">微信登录</a>
</body>
</html>

6.拉起微信的登录二维码页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>微信登录</title>

    <link rel="icon" href="/static/images/wx.ico">
</head>
<body>
<script type="text/javascript" src="https://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js"></script>
    <div style="Text-align:center;width:100%;">
        <div id="login_container"></div>
    </div>
<script type="text/javascript">
    var obj = new WxLogin({
        self_redirect:false,
        id:"login_container",
        appid: "wxd853562a0548a7d0",
        scope: "snsapi_login",
        redirect_uri: "http://bugtracker.itsource.cn/wechat/callback",
        state: "xxx",
        style: "black",
        href: ""
    });
</script>

</body>
</html>
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值