Objective 1: There are project development needs, personally step on numerous pits, online difficult to have a suitable full set, so output return society

Objective 2: several years, always white whoring inappropriate, come out to mix always return

Goal 3: Debut. There’s always a first time for everything

1. The flow chart

2. Configure the menu

The menu can be directly configured as follows: wechat authentication path (fixed writing) + forwarding address (forwarding address is usually the front page)

https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx77777777&redirect_uri=http%3A%2F%2F7d.natapp.cc&response_typ e=code&scope=snsapi_userinfo&state=STATE#wechat_redirectCopy the code

The JAVA code is as follows:

/** * Obtain wechat authorization * This request needs to be configured in the public account menu as a start */
@apiOperation (" Jump to wechat authentication ")
@RequestMapping("/wxLoginInit")
public void loginInt(HttpServletResponse response) throws IOException {
    String APP_ID = "MP_APPID";
    String BACK_URL = "BACK_URL";
    // Splice the address
    String url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid="
            +APP_ID
            + "&redirect_uri="
            + URLEncoder.encode(BACK_URL,"UTF-8")
            + "&response_type=code"
            + "&scope=snsapi_userinfo"
            + "&state=STATE#wechat_redirect";
    // Redirect to the redirect address
    log.info(Get code,redirectURL={}", url);
    response.sendRedirect(url);
}
Copy the code

Note:

1. The forwarding address must be in the trusted domain and must be added http://, must URLEncoder

2. In the authorized domain name of the webpage, wechat public account requires the following files to be uploaded to the directory of the Web server (or virtual host) specified by the domain name or path

This file must be stored in the front-end root directory, can use nginx as the proxy, put in the nginx/ HTML target to pass the domain name verification

3. The access code

The front-end page gets the request, grabs the code from the request

/ / from the request intercept code window. Let code = location. The href. Match (/ code = (\ S *) & /)? window.location.href.match(/code=(\S*)&/)[1] : '';Copy the code

4. Exchange code for information

After the front-end gets the code, it sends a request to the background to get the required information, including openId and so on

WxMpService wxMpService = WxMpConfig.getWxMpService();
// Get access_toke according to code
WxMpOAuth2AccessToken accessToken = wxMpService.oauth2getAccessToken(code);
String lang = "zh_CN";
// Obtain basic user information based on access_token
WxMpUser wxMpUser = wxMpService.oauth2getUserInfo(accessToken, lang);
String openId = wxUserInfo.getOpenId();
Copy the code

5. Obtain system users based on openId

According to the openId obtained, check whether there is a corresponding user in the system. If there is, you can directly log in to generate token. If not, you can return an error message and let the front end guide to the login and registration page

// Use openId to find the user
User byAccount = userService.getByAccount(openId);
if(ToolUtil.isNotEmpty(byAccount)){
    Map returnData = new HashMap<>();
    String token = authService.login(openId);
    returnData.put("token", token);
    returnData.put("wxUserInfo", wxUserInfo);
    return ResponseData.success(returnData);
}else {
    return ResponseData.error("User not registered!");
}
Copy the code

6. Front-end storage tokens

This project is the UNIAPP framework, and other front-end is similar. After getting the token, it is stored in LocalStorage

uni.request({
    url: 'https://www.example.com/wechat/getUserInfo'.// This is an example, not a real interface address.
    data: {
        'token': token
    },
    header: {
        'custom-header': 'hello' // Customize the request header
        'X-Requested-With': 'XMLHttpRequest'."Accept": "application/json"."Content-Type": "application/json; charset=UTF-8"
    },
    success: (res) = > {
        console.log(res.data.data.token);
        this.text = 'request success'; }});Copy the code

7. The front-end requests data

All front-end requests attach tokens from LocalStorage to the request header to request background data

8. Complete code

8.1 the pom. XML
<! -- wechat public account Development kit -->
<dependency>
    <groupId>com.github.binarywang</groupId>
    <artifactId>weixin-java-mp</artifactId>
    <version>3.8.0</version>
</dependency>
Copy the code
8.2 the background
@Controller
@RequestMapping("/wechat")
@Slf4j
public class WechatController {

    @Autowired
    private UserService userService;

    @Autowired
    private AuthService authService;

    /** * Obtain wechat authorization * This request needs to be configured in the public account menu as a start */
    @apiOperation (" Jump to wechat authentication ")
    @RequestMapping("/wxLoginInit")
    public void loginInt(HttpServletResponse response) throws IOException {
        String APP_ID = (String) ConstantsContext.getConstntsMap().get("MP_APPID");
        String BACK_URL = (String) ConstantsContext.getConstntsMap().get("BACK_URL");
        String url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid="
                +APP_ID
                + "&redirect_uri="
                + URLEncoder.encode(BACK_URL,"UTF-8")
                + "&response_type=code"
                + "&scope=snsapi_userinfo"
                + "&state=STATE#wechat_redirect";
        // Redirect to the redirect address
        log.info(Get code,redirectURL={}", url);
        response.sendRedirect(url);
    }

    /** * Obtain personal basic information according to code *@param code
     * @return
     * @throws Exception
     */
    @PostMapping("/getUserInfo")
    @ResponseBody
    public ResponseData getUserInfo(String code,HttpServletResponse response) throws Exception {
        WxMpService wxMpService = WxMpConfig.getWxMpService();
        // Get access_toke according to code
        WxMpOAuth2AccessToken accessToken = wxMpService.oauth2getAccessToken(code);
        String lang = "zh_CN";
        // Obtain basic user information based on access_token
        WxMpUser wxUserInfo = wxMpService.oauth2getUserInfo(accessToken, lang);
        String openId = wxUserInfo.getOpenId();
        // Use openId to find the user
        User byAccount = userService.getByAccount(openId);
        if(ToolUtil.isNotEmpty(byAccount)){
            Map returnData = new HashMap<>();
            String token = authService.login(openId);
            returnData.put("token", token);
            returnData.put("wxUserInfo", wxUserInfo);
            return ResponseData.success(returnData);
        }else {
            return ResponseData.error("User not registered!"); }}}Copy the code
8.3 the front (uniapp)

Encapsulate request api.js

const baseUrl = 'localhost:17000';

/** * Common request */
const httpRequest = (opts, data) = > {
	let httpDefaultOpts = {
		url: baseUrl + opts.url,
		data: data,
		method: opts.method,
		header: opts.method == 'get' ? {
			'X-Requested-With': 'XMLHttpRequest'."Accept": "application/json"."Content-Type": "application/json; charset=UTF-8"}, {'X-Requested-With': 'XMLHttpRequest'.'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
		},
		dataType: 'json',}let promise = new Promise(function(resolve, reject) {
		uni.request(httpDefaultOpts).then(
			(res) = > {
				resolve(res[1])
			}
		).catch(
			(response) = > {
				reject(response)
			}
		)
	})
	return promise
};

/** * Request */ with Token
const httpTokenRequest = (opts, data) = > {
	let token = "";
	uni.getStorage({
		key: 'token'.success: function(ress) {
			token = ress.data
		}
	});
	// The token is saved in the storage after successful login
	let httpDefaultOpts = {
		url: baseUrl + opts.url,
		data: data,
		method: opts.method,
		header: opts.method == 'get' ? {
			'Authorization': token,
			'X-Requested-With': 'XMLHttpRequest'."Accept": "application/json"."Content-Type": "application/json; charset=UTF-8"}, {'Authorization': token,
			'X-Requested-With': 'XMLHttpRequest'.'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
		},
		dataType: 'json',}let promise = new Promise(function(resolve, reject) {
		uni.request(httpDefaultOpts).then(
			(res) = > {
				resolve(res[1])
			}
		).catch(
			(response) = > {
				reject(response)
			}
		)
	})
	return promise
};

export default {
	baseUrl,
	httpRequest,
	httpTokenRequest
}

Copy the code

App.vue

<script>
	export default {
		onLaunch: function() {
			const wxUserInfo = uni.getStorageSync('wxUserInfo');
			if(! wxUserInfo) {console.log('Request personal information! ');
				// Intercepts code from the request
				let code = window.location.href.match(/code=(\S*)&/)?window.location.href.match(/code=(\S*)&/) [1] :
					' ';
				if (code) {
					let opts = {
						url: '/wechat/getUserInfo'.method: 'POST'
					};
					let param = {
						"code": code
					};
					this.$myRequest.httpTokenRequest(opts, param).then(
						res= > {
							let token = res.data.data.token;
							let wxUserInfo = res.data.data.wxUserInfo;
							uni.setStorageSync('wxUserInfo', wxUserInfo);
							uni.setStorageSync('token', token);
						},
						error= > {
							uni.navigateTo({
								url: "pages/register/register"})})}else {
					console.error("Code fetch failed!!");
					uni.navigateTo({
						url: "pages/register/register"}}})else {
				console.log("Normal Online");
			}
		}
	}
</script>

<style>
	/* Common CSS for each page */
</style>
Copy the code

main.js

import Vue from 'vue'
import App from './App'

Vue.config.productionTip = false

App.mpType = 'app'

import myRequest from './pages/base/api.js';
Vue.prototype.$myRequest = myRequest;

const app = newVue({ ... App }) app.$mount()Copy the code

Finally, thanks to the Nuggets for this platform, really good