preface

Wechat login webpage authorization and APP authorization wechat JSAPI payment wechat APP payment wechat APP and JSAPI refund Alipay mobile phone website payment Alipay APP payment alipay refund above I have put personal public number, search a search: JAVA thief ship, the end of the article has a public number two-dimensional code! Feel that personal development will be used in the future can pay attention to oh! Take fewer detours…

The official documentation

H5 wechat login authorization document address

Developers.weixin.qq.com/doc/offiacc…

APP wechat login authorization

Developers.weixin.qq.com/doc/oplatfo…

IOS Access Guide

Developers.weixin.qq.com/doc/oplatfo…

Android Access Guide

Developers.weixin.qq.com/doc/oplatfo…

Process steps

H5 wechat login authorization
  • Enter the authorization page to approve authorization and obtain the code
  • Exchange web page authorization access_token with code (different from access_token in base support)
  • If necessary, developers can refresh the web license access_token to avoid expiration
  • Access to basic user information through web authorization Access_token and OpenID (support UnionID mechanism)

Scope snsapi_base and scope snsapi_userinfo

Snsapi_base is silently authorized and automatically jumps to the callback page, while snsapi_userinfo is manually approved by the user.

Question 2: What is the difference between access_token and access_token?

When a common access_token obtains user information, the information is null if the user is not concerned. However, the access_token of web authorization can be obtained with the user’s permission, regardless of whether the user is concerned or not.

Question 3: What is the difference between UnionID and OpenID?

Unionid is the same for different applications under the same wechat open platform (mobile applications, website applications and public accounts).

However, OpenID is different for different applications under the same wechat open platform. For example, if the user authorizes application A and application B, the two Openids of the user are different, and one application corresponds to one OpenID. If the user authorizes application A again, the OpenID will remain unchanged.

Question 4: ** About the UnionID mechanism

That is, if developers have multiple public accounts, or need to unify user accounts between public accounts and mobile applications, they need to go to wechat open platform (open.weixin.qq.com) to bind public accounts, and then they can use the UnionID mechanism to meet the above requirements.

The pit of tread
  • Redirect_uri The domain name is inconsistent with background configuration

Solution: in the public number set – function set – web page authorization, configure front-end storage TXT file path, such as www.xxx.com/static, and then click submit, you can test can access to TXT content in advance.

  • Get wechat user information, returned unionID is empty

Solution: Go to wechat open platform, bind the public account, done

APP wechat login authorization
  • After a third party initiates a wechat authorized login request and a wechat user authorizes a third-party application, wechat will pull up the application or redirect it to the third-party website, and bring the code parameter of the authorized temporary note.
  • Access_token is exchanged via API with code parameter plus AppID, AppSecret, etc.
  • The access_token interface is invoked to obtain basic data resources or help users to perform basic operations.

The preparatory work

Natapp Intranet penetration tool

This tool can be used to obtain domain names during development

Get AppID and AppSecret

Go to the wechat open platform (open.weixin.qq.com) to check the corresponding application details

Example Modify the authorization callback domain name

Go to the configuration option of “Official account function-Function Setting” on the official website of the public platform and configure the webpage authorization callback domain name according to the specification

Code implementation (including APP and H5)

Configuration parameters

application.yml

# Wechat related configuration
wx:
  # merchant ID
  MCH_ID: 
  # Project base domain name
  BASEURL: 
  # wechat Login - callback domain name after user consent (front-end domain name)
  URL: 
  # APP_ID
  H_APP_ID: 
  # public key
  H_APP_SECRET: 
  # app的APP_ID
  A_APP_ID: 
  # APP's secret key
  A_APP_SECRET: 
  # wechat Login - wechat authorized basic address
  LOGIN_AUTH_BASE_URL: https://open.weixin.qq.com/connect/oauth2/authorize?
  # wechat Login - Get the ACCESS_TOKEN URL
  LOGIN_ACCESS_TOKEN_URL: https://api.weixin.qq.com/sns/oauth2/access_token?
  # wechat Login - url to get the login information
  LOGIN_USER_INFO_URL: https://api.weixin.qq.com/sns/userinfo?
  # wechat login - callback address after user consent (front-end address)
  LOGIN_RETURN_URL: ${wx.URL}/static/weixinShouQuan.html
  # wechat login - application authorization scope, snsapi_base (no authorization page, direct redirection, can only get user openID), snsapi_userinfo
  # (Open the authorization page, you can get the nickname, gender, location through OpenID. And, even in the absence of attention, as long as the user's authorization can be accessed)
  SCOPE: snsapi_userinfo
Copy the code
Read the parameter

YmlParament

/** * get the yML parameter entity */
@Component
@Data
public class YmlParament {
	/* wechat related fields */
	@Value("${wx.BASEURL}")
	private String baseurl;

	@Value("${wx.H_APP_ID}")
	private String h_app_id;
	
    @Value("${wx.A_APP_ID}")
	private String a_app_id;
    
	@Value("${wx.H_APP_SECRET}")
	private String h_app_secret;
    
    @Value("${wx.A_APP_SECRET}")
	private String a_app_secret;

	@Value("${wx.LOGIN_ACCESS_TOKEN_URL}")
	private String login_access_token_url;

	@Value("${wx.LOGIN_USER_INFO_URL}")
	private String login_user_info_url;

	@Value("${wx.LOGIN_AUTH_BASE_URL}")
	private String login_auth_base_url;

	@Value("${wx.LOGIN_RETURN_URL}")
	private String login_return_url;

	@Value("${wx.SCOPE}")
	private String scope;
}
Copy the code
Access code
  • H5 access code

The front end gets the authorization URL from the background, and then the front end requests the URL to get the code and then requests the background

WxController

	@ApiOperation("Get authorization URL")
	@PostMapping("/getWeiXinLoginUrl")
	public R getWeiXinLoginUrl(a) throws Exception {
		String url = ymlParament.getLogin_auth_base_url() + "appid=" + ymlParament.getH_app_id()+ "&redirect_uri=" + ymlParament.getLogin_return_url()
+ "&response_type=code"+ "&scope=snsapi_userinfo" + "&state=STATE#wechat_redirect";	
        // return the result to the front end
		return R.ok().data("redirectUrl", url);
	}
Copy the code
  • APP access code

In APP, the front end uses SDK to request authorization login, and the user gets the code after agreeing to authorization and then requests the background

Examples of access codes for iOS application authorization login (see the iOS Access Guide) :

- (void)sendAuthRequest
{
	// Construct SendAuthReq
	SendAuthReq* req =[[[SendAuthReq alloc]init]autorelease];
	req.scope = @"snsapi_userinfo";
	req.state = @"123";
	// The third party sends a SendAuthReq message structure to the wechat terminal
	[WXApi sendReq:req];
}
Copy the code

Examples of access codes for Authorized login of Android applications (see the Android Access Guide) :

{
	// send oauth request
	Final SendAuth.Req req = new SendAuth.Req();
	req.scope = "snsapi_userinfo";
	req.state = "wechat_sdk_demo_test";
	api.sendReq(req);
}
Copy the code
Obtain web authorization access_token by code, and then pull user information by access_token and OpenID

WxController

/* both H5 and app can call */
	@ApiOperation("Obtain wechat user information")
	@PostMapping(value = "/getWxUserInFo")
	public R getWxUserInFo(@RequestBody String body) throws Exception {
		String state = JacksonUtil.parseString(body, "state");
		String code = JacksonUtil.parseString(body, "code");
        // Indicate which application to use to get the corresponding appID and appSecret
		Integer openIdType = JacksonUtil.parseInteger(body, "openIdType");
		//1
		if(IsNull.isNull(code) || IsNull.isNull(state)) {
			return R.error("Parameters cannot be empty.");
		}
		/ / 2, through code acquisition accesstoken, UserWxOpenidEums is used to record the application, such as type1 is xxAPP, type2 is xx service numberJSONObject accessToken=WxUtils.getAccessTokenByCode(code, openIdType==UserWxOpenidEums.TYPE_1.getKey()? ymlParament.getA_app_id():ymlParament.getH_app_id(), openIdType==UserWxOpenidEums.TYPE_1.getKey()? ymlParament.getA_app_secret():ymlParament.getH_app_secret(), ymlParament.getLogin_access_token_url());//3. Obtain user informationJSONObject userinfo=WxUtils.getUserinfo(openIdType==UserWxOpenidEums.TYPE_1.getKey()? ymlParament.getA_app_id():ymlParament.getH_app_id(), accessToken.getString("openid"), accessToken.getString("access_token"), ymlParament.getLogin_user_info_url());
		if(! IsNull.isNull(userinfo.getString("errcode"))) {return R.error(userinfo.getString("errmsg"));
	}
		return R.ok().data("token", token).data("userinfo",userinfo);
}

Copy the code

WxUtils

	/ * * * = = = = = = = = = = = = = > > logged in < < = = = = = = = = = = = = = * * the second step through code access access_token * right when the returned JSON packet is as follows:  * { "access_token":"ACCESS_TOKEN", "expires_in":7200, "refresh_token":"REFRESH_TOKEN", "openid":"OPENID", "scope":"SCOPE" } */
	public static JSONObject getAccessTokenByCode(String code,String appId,String appSecret,String login_access_token_url) throws Exception {
		Map<String, String> map = new HashMap<String, String>();
		map.put("appid",appId);
		map.put("secret",appSecret);
		map.put("code",code);
		map.put("grant_type"."authorization_code");
		return (JSONObject)JSON.parse(HttpUtil.get(login_access_token_url, map));
	}
	
	/ * * * = = = = = = = = = = = = = > > logged in < < = = = = = = = = = = = = = * step 3: refresh access_token (if required) * right when the returned JSON data packet is as follows:  * { "access_token":"ACCESS_TOKEN", "expires_in":7200, "refresh_token":"REFRESH_TOKEN", "openid":"OPENID", "scope":"SCOPE" } */
	public static JSONObject refreshAccessToken(String appid,String refresh_token) throws Exception {
		Map<String, String> map = new HashMap<>();
		map.put("appid",appid);
		map.put("grant_type"."refresh_token");
		map.put("refresh_token",refresh_token);
		return (JSONObject)JSON.parse(HttpUtil.get("https://api.weixin.qq.com/sns/oauth2/refresh_token?", map));
	}
	
	/ * * * = = = = = = = = = = = = = > > logged in < < = = = = = = = = = = = = = * fourth, get the user information * access_token obtained through code * right when the returned JSON packet is as follows:  * { "openid":" OPENID", "nickname": NICKNAME, "sex":"1", "province":"PROVINCE", "city":"CITY", "country":"COUNTRY", "headimgurl": "http://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavH iaiceqxibJxCfHe/46", "privilege":[ "PRIVILEGE1" "PRIVILEGE2" ], "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL" } *@throws Exception 
	 */
	public static JSONObject getUserinfo(String appid,String openid,String accessToken,String login_user_info_url) throws Exception {
		AccessToken = accessToken = accessToken
		HashMap<String, String> param =new HashMap<String, String>();
		param.put("access_token", accessToken);
		param.put("openid", openid);
		JSONObject check=(JSONObject)JSON.parse(HttpUtil.get("https://api.weixin.qq.com/sns/auth?access_token="+accessToken+"&openid="+openid, param));
		// Check whether access_token is valid and refresh accessToken if accessToken is invalid
		if(! check.getString("errcode").equals("0")) {
			accessToken=refreshAccessToken(appid, accessToken).getString("refresh_token");
		}
		param =new HashMap<String, String>();
		param.put("openid",openid);
	param.put("access_token",accessToken);
		param.put("lang"."zh_CN");
	return (JSONObject) JSON.parse(HttpUtil.get(login_user_info_url, param));
	}
Copy the code
Utility class

HttpUtil

public static String get(String urlStr, Map<String, String> parameters) throws IOException {
		URL url = new URL(urlStr);
		HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
		httpURLConnection.setDoInput(true);
		httpURLConnection.setDoOutput(true); // Set the connection to output
		httpURLConnection.setRequestMethod("GET"); // Set the request mode
		httpURLConnection.setRequestProperty("charset"."utf-8");
		PrintWriter pw = new PrintWriter(new BufferedOutputStream(httpURLConnection.getOutputStream()));

		StringBuffer parameter = new StringBuffer();
		parameter.append("1 = 1");
		for (Entry<String, String> entry : parameters.entrySet()) {
			parameter.append("&" + entry.getKey() + "=" + entry.getValue());
		}
		pw.write(parameter.toString());// Write data to the connection (equivalent to sending data to the server)
		pw.flush();
		pw.close();
    
		BufferedReader br = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream(), "utf-8"));
		String line = null;
		StringBuilder sb = new StringBuilder();
		while((line = br.readLine()) ! =null) { // Read data
			sb.append(line + "\n");
	}
		br.close();
	return sb.toString();
	}
Copy the code

JacksonUtil

public class JacksonUtil {
    public static String parseString(String body, String field) {
        ObjectMapper mapper = new ObjectMapper();
        JsonNode node;
        try {
            node = mapper.readTree(body);
            JsonNode leaf = node.get(field);
            if(leaf ! =null) {
                returnleaf.asText(); }}catch (IOException e) {
        	e.printStackTrace();
        }
        return null;
    }
    
    public static Integer parseInteger(String body, String field) {
        ObjectMapper mapper = new ObjectMapper();
        JsonNode node;
        try {
            node = mapper.readTree(body);
            JsonNode leaf = node.get(field);
            if(leaf ! =null) {
                returnleaf.asInt(); }}catch (IOException e) {
        	e.printStackTrace();
      }
        return null; }}Copy the code
Thank you for watching, like you can pay attention to oh! A share Java learning resources, technical articles, practical experience of the public account ~

Welcome to pay attention to the public number oh ~