WeChat authorizes third-party app login

WeChat login access

WeChat login follows the authorization code mode in the protocol Auth2.0

Let's take a look at how the authorization code mode in Auth2.0 is defined:

The authorization code mode (authorization code) is the authorization mode with the most complete functions and the most rigorous process. Its characteristic is to interact with the authentication server of the "service provider" through the background server of the client. 
Its steps are as follows:

(A) The user accesses the client, which directs the former to the authentication server.

(B) The user chooses whether to authorize the client.

(C) Assuming that the user grants authorization, the authentication server directs the user to the "redirection URI" (redirection URI) specified by the client in advance, and attaches an authorization code at the same time.

(D) The client receives the authorization code, attaches the previous "redirect URI", and applies for a token to the authentication server. This step is done on the server in the background of the client and is not visible to the user.

(E) The authentication server checks the authorization code and the redirection URI, and after confirming that it is correct, sends an access token (access token) and a refresh token (refresh token) to the client

 

Step 1. Request code

{
    // send oauth request
     Final SendAuth.Req req = new SendAuth.Req();
     req.scope = "snsapi_userinfo";
     req.state = "wechat_sdk_demo_test";
     api.sendReq(req);
    }

Use this code to request the authorization code code from the WeChat open platform, you can pull up WeChat and open the authorization login page (provided that you have installed the WeChat application and have logged in, if you have not logged in, you will be directed to log in first), as shown below:

1. If the WeChat authorization page is not displayed, please check whether your APP signature is consistent with your APP signature on the Tencent Open Platform. If it is inconsistent, you can modify the APP signature on the Tencent Open Platform. After modification, reinstall WeChat or clear WeChat data and try again .

2. Create a new wxapi directory under the corresponding directory of your package name, and add a new WXEntryActivity class under the wxapi directory, which inherits from Activity (for example, if the package name of the application is net.sourceforge, the new package name is : net.sourceforge.wxapi), it should be noted here that the package name should not be mistaken , and the name of the new class must be WXEntryActivity.

Return instructions 
After the user clicks Authorize, the WeChat client will be pulled up and redirected to the authorization interface. The user clicks Allow or Cancel on this interface, and the SDK returns data to the caller through the Resp of SendAuth. Call back the onResp(BaseResp resp) method in WXEntryActivity, as follows:

 1 @Override
 2     public void onResp(BaseResp resp) {
 3         int errorCode = resp.errCode;
 4         switch (errorCode) {
 5         case BaseResp.ErrCode.ERR_OK:
 6             //用户同意
 7             String code = ((SendAuth.Resp) resp).code;
 8             break;
 9         case BaseResp.ErrCode.ERR_AUTH_DENIED:
10             //用户拒绝
11             break;
12         case BaseResp.ErrCode.ERR_USER_CANCEL:
13             //用户取消
14             break;
15         default:
16             break;
17         }
18         ToastUtil.showMessageLong(this, resp.errStr);
19     }

After receiving the authorization code, the client initiates a login request to its own server with the received authorization code attached.

The server receives the login request and requests the access_token from the WeChat open platform, and the WeChat open platform returns a Json string:

Step 2: Obtain access_token through code (do it on your own server side)

After obtaining the code of the first step, request the following link to obtain an access_token:

https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

1 private String getAccessToken(String code) {
 2         String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
 3         URI uri = URI.create(url);
 4         HttpClient client = new DefaultHttpClient();
 5         HttpGet get = new HttpGet(uri);
 6 
 7         HttpResponse response;
 8         try {
 9             response = client.execute(get);
10             if (response.getStatusLine().getStatusCode() == 200) {
11                 HttpEntity entity = response.getEntity();
12 
13                 BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent(), "UTF-8"));
14                 StringBuilder sb = new StringBuilder();
15 
16                 for (String temp = reader.readLine(); temp != null; temp = reader.readLine()) {
17                     sb.append(temp);
18                 }
19 
20                 JSONObject object = new JSONObject(sb.toString().trim());
21                 accessToken = object.getString("access_token");
22                 openID = object.getString("openid");
23                 refreshToken = object.getString("refresh_token");
24                 expires_in = object.getLong("expires_in");
25                 return accessToken;
26             }
27         } catch (ClientProtocolException e) {
28             // TODO Auto-generated catch block 
29             e.printStackTrace();
30         } catch (IOException e) {
31             // TODO Auto-generated catch block
32             e.printStackTrace();
33         } catch (IllegalStateException e) {
34             // TODO Auto-generated catch block
35             e.printStackTrace();
36         } catch (JSONException e) {
37             // TODO Auto-generated catch block
38             e.printStackTrace();
39         }
40 
41         return null;
42     }

Parameter Description

参数        是否必须        说明 
appid       是        应用唯一标识,在微信开放平台提交应用审核通过后获得

secret      是        应用密钥AppSecret,在微信开放平台提交应用审核通过后获得

code        是        填写第一步获取的code参数

grant_type  是        填authorization_code回说明**

correctly returns:

1 { 
2 "access_token":"ACCESS_TOKEN", 
3 "expires_in":7200, 
4 "refresh_token":"REFRESH_TOKEN",
5 "openid":"OPENID", 
6 "scope":"SCOPE",
7 "unionid":"o6_bmasdasdsad6_2sgVt7hMZOPfL"
8 }
 参数                              说明
access_token                    接口调用凭证
expires_in  access_token        接口调用凭证超时时间,单位(秒)
refresh_token                   用户刷新access_token
openid                          授权用户唯一标识
scope                           用户授权的作用域,使用逗号(,)分隔
unionid                         只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段。


The server receives the returned access_token, and returns data such as access_token, expires_in, and access_token to the client, and the client successfully logs in

The client can use the existing access_token to obtain WeChat user information

Step 3: Call the interface through access_token

After obtaining the access_token, the interface call must have the following prerequisites:

  1. access_token is valid and has not timed out;
  2. The WeChat user has authorized the corresponding interface scope of the third-party application account.

For the interface scope (scope), the interfaces that can be called are as follows:

授权作用域(scope)             接口                接口说明
snsapi_base       /sns/oauth2/access_token     通过code换取access_token、refresh_token和已授权scope
                    /sns/oauth2/refresh_token  刷新或续期access_token使用
                    /sns/auth                  检查access_token有效性
snsapi_userinfo    /sns/userinfo               获取用户个人信息

其中snsapi_base属于基础接口,若应用已拥有其它scope权限,则默认拥有snsapi_base的权限。使用snsapi_base可以让移动端网页授权绕过跳转授权登录页请求用户授权的动作,直接跳转第三方网页带上授权临时票据(code),但会使得用户已授权作用域(scope)仅为snsapi_base,从而导致无法获取到需要用户授权才允许获得的数据和基础功能。

以获取用户信息为例:
 1 private void getUserInfo() {
 2         if (isAccessTokenIsInvalid() && System.currentTimeMillis() < expires_in) {
 3             String uri = "https://api.weixin.qq.com/sns/userinfo?access_token=" + accessToken + "&openid=" + openID;
 4             HttpClient client = new DefaultHttpClient();
 5             HttpGet get = new HttpGet(URI.create(uri));
 6             try {
 7                 HttpResponse response = client.execute(get);
 8                 if (response.getStatusLine().getStatusCode() == 200) {
 9                     BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
10                     StringBuilder builder = new StringBuilder();
11                     for (String temp = reader.readLine(); temp != null; temp = reader.readLine()) {
12                         builder.append(temp);
13                     }
14                     JSONObject object = new JSONObject(builder.toString().trim());
15                     String nikeName = object.getString("nickname");
16                 }
17             } catch (ClientProtocolException e) {
18                 // TODO Auto-generated catch block
19                 e.printStackTrace();
20             } catch (IOException e) {
21                 // TODO Auto-generated catch block
22                 e.printStackTrace();
23             } catch (JSONException e) {
24                 // TODO Auto-generated catch block
25                 e.printStackTrace();
26             }
27         }
28     }

WeChat repeated login

Assuming that the user has been authorized, the next time you log in, you only need to verify whether the access_token is valid, if it is invalid, re-authorize, and if it is valid, you do not need to re-authorize.

1. The user requests to log in from his own server, and the login method is WeChat login, with the access_token returned from the last login

2. The server receives the user's login request, and sends a verification request to the WeChat open platform to verify whether the access_token is valid as follows :

1 private boolean isAccessTokenIsInvalid() {
 2         String url = "https://api.weixin.qq.com/sns/auth?access_token=" + accessToken + "&openid=" + openID;
 3         URI uri = URI.create(url);
 4         HttpClient client = new DefaultHttpClient();
 5         HttpGet get = new HttpGet(uri);
 6         HttpResponse response;
 7         try {
 8             response = client.execute(get);
 9             if (response.getStatusLine().getStatusCode() == 200) {
10                 HttpEntity entity = response.getEntity();
11 
12                 BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent(), "UTF-8"));
13                 StringBuilder sb = new StringBuilder();
14 
15                 for (String temp = reader.readLine(); temp != null; temp = reader.readLine()) {
16                     sb.append(temp);
17                 }
18                 JSONObject object = new JSONObject(sb.toString().trim());
19                 int errorCode = object.getInt("errcode");
20                 if (errorCode == 0) {
21                     return true;
22                 }
23             }
24         } catch (ClientProtocolException e) {
25             // TODO Auto-generated catch block
26             e.printStackTrace();
27         } catch (IOException e) {
28             // TODO Auto-generated catch block
29             e.printStackTrace();
30         } catch (JSONException e) {
31             // TODO Auto-generated catch block
32             e.printStackTrace();
33         }
34         return false;
35     }

Return instructions:

1 正确的Json返回结果:
2 { 
3 "errcode":0,"errmsg":"ok"
4 }
5 错误的Json返回示例:
6 { 
7 "errcode":40003,"errmsg":"invalid openid"
8 }

If the access_token is valid, the server returns the information to the client, and the client logs in successfully.

If the access_token is invalid, the server sends a request to refresh the access_token to the WeChat open platform as follows:

The access_token is the calling credential for calling the authorization relationship interface. Since the validity period of the access_token (currently 2 hours) is short, when the access_token expires, you can use the refresh_token to refresh it. There are two types of access_token refresh results:

1. If the access_token has timed out, performing a refresh_token will obtain a new access_token and a new timeout period;  
2. If the access_token has not timed out, performing a refresh_token will not change the access_token, but the timeout period will be refreshed, which is equivalent to renewing the access_token.

The refresh_token has a longer validity period (30 days). When the refresh_token expires, the user needs to re-authorize.

1 private void refreshAccessToken() {
 2         String uri = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=" + ShareUtil.APP_ID + "&grant_type=refresh_token&refresh_token="
 3                 + refreshToken;
 4         HttpClient client = new DefaultHttpClient();
 5         HttpGet get = new HttpGet(URI.create(uri));
 6         try {
 7             HttpResponse response = client.execute(get);
 8             if (response.getStatusLine().getStatusCode() == 200) {
 9                 BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
10                 StringBuilder builder = new StringBuilder();
11                 for (String temp = reader.readLine(); temp != null; temp = reader.readLine()) {
12                     builder.append(temp);
13                 }
14                 JSONObject object = new JSONObject(builder.toString().trim());
15                 accessToken = object.getString("access_token");
16                 refreshToken = object.getString("refresh_token");
17                 openID = object.getString("openid");
18                 expires_in = object.getLong("expires_in");
19             }
20         } catch (ClientProtocolException e) {
21             // TODO Auto-generated catch block
22             e.printStackTrace();
23         } catch (IOException e) {
24             // TODO Auto-generated catch block
25             e.printStackTrace();
26         } catch (JSONException e) {
27             // TODO Auto-generated catch block
28             e.printStackTrace();
29         }
30     }

Return instructions:

1 正确的返回:
 2 { 
 3 "access_token":"ACCESS_TOKEN", 
 4 "expires_in":7200, 
 5 "refresh_token":"REFRESH_TOKEN", 
 6 "openid":"OPENID", 
 7 "scope":"SCOPE" 
 8 }
 9 参数                    说明
10 access_token       接口调用凭证
11 expires_in        access_token接口调用凭证超时时间,单位(秒)
12 refresh_token     用户刷新access_token
13 openid           授权用户唯一标识
14 scope          用户授权的作用域,使用逗号(,)分隔
15 
16 错误返回样例:
17 {
18 "errcode":40030,"errmsg":"invalid refresh_token"
19 }

3. The server obtains the new access_token and other information, and returns it to the client. The client successfully logs in or obtains authorization again.

Guess you like

Origin blog.csdn.net/weixin_43845075/article/details/104628385