微信授權登錄(java實現)

微信公衆平臺開發文檔

微信授權登錄獲取用戶信息有2種方式:
1.靜默授權獲取用戶信息、
2.非靜默授權彈出授權界面,用戶確認之後獲取用戶信息(這種方法能夠獲取到更多信息)。

開發前準備:

1.獲取到AppID
2.AppSecret
3.設置IP白名單
4.添加網頁授權域名
公衆號設置->功能設置

前端獲取code:

https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect

在這裏插入圖片描述

通過code換取網頁授權access_token

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

拉取用戶信息

https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN

<dependency>
    <groupId>com.github.kevinsawicki</groupId>
    <artifactId>http-request</artifactId>
    <version>6.0</version>
</dependency>
<dependency>
   <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.4</version>
    <scope>provided</scope>
</dependency>
package com.pica.cloud.patient.resident.server.util;

import com.alibaba.fastjson.JSON;
import com.github.kevinsawicki.http.HttpRequest;
import com.pica.cloud.patient.resident.common.constants.CommonCons;
import com.pica.cloud.patient.resident.server.configuration.BeanConfiguration;
import com.pica.cloud.patient.resident.server.vo.AccessTokenVo;
import com.pica.cloud.patient.resident.server.vo.WechatUserInfoVo;
import lombok.extern.slf4j.Slf4j;
import lombok.var;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @ClassName WechatUtil
 * @Description
 * @Author Jun.li0101
 * @Date 2019/3/19 16:43
 * @ModifyDate 2019/3/19 16:43
 * @Version 1.0
 */
@Component
@Slf4j
public class WechatUtil {
    private static BeanConfiguration configuration;
    private final static Integer SUCCESS = 0;

    @Autowired
    public WechatUtil(BeanConfiguration config) {
        WechatUtil.configuration = config;
    }

    public static AccessTokenVo getWechatAccessToken(String code) {
        if (code == null) {
            return null;
        }
        String url = String.format(CommonCons.Wechat.LOGIN_ACCESS_TOKEN_URL, configuration.getAppId(), configuration.getAppSecret(), code);
        try {
            String result = HttpRequest.get(url).body();
            log.info("getWechatAccessToken result:{}", result);
            var token = JSON.parseObject(result, AccessTokenVo.class);
            if (token.getErrCode() == null || SUCCESS.equals(token.getErrCode())) {
                log.info("get wechat access token:{}", token);
                return token;
            } else {
                log.warn("code {} request wechat api get access token error:{}", code, token);
            }
        } catch (Exception ex) {
            log.error("getWechatAccessToken error", ex);
        }
        return null;
    }

    public static WechatUserInfoVo getWechatUserInfo(AccessTokenVo tokenVo) {
        if (tokenVo == null) {
            return null;
        }
        var url = String.format(CommonCons.Wechat.GET_USER_INFO_URL, tokenVo.getAccessToken(), tokenVo.getOpenId());
        try {
            String result = HttpRequest.get(url).body();
            var info = JSON.parseObject(result, WechatUserInfoVo.class);
            if (info.getErrCode() == null || SUCCESS.equals(info.getErrCode())) {
                log.info("get wechat user info:{}", info);
                return info;
            } else {
                log.warn("request wechat api get user information error:{}", info);
            }
        } catch (Exception ex) {
            log.error("getWechatUserInfo error", ex);
        }
        return null;
    }

}


package com.pica.cloud.patient.resident.server.vo;

import com.alibaba.fastjson.annotation.JSONField;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

/**
 * @ClassName AccessTokenVo
 * @Description {@link} 參考 https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419317851&token=&lang=zh_CN
 * @Author Jun.li0101
 * @Date 2019/3/19 17:15
 * @ModifyDate 2019/3/19 17:15
 * @Version 1.0
 */
@Getter
@Setter
@ToString
public class AccessTokenVo extends WechatCommonVo {

    @JSONField(format = "access_token")
    private String accessToken;

    @JSONField(format = "expires_in")
    private Integer expiresIn;

    @JSONField(format = "refresh_token")
    private String refreshToken;

    @JSONField(format = "openid")
    private String openId;

    @JSONField(format = "scope")
    private String scope;

    @JSONField(format = "unionid")
    private String unionId;

}

//
package com.pica.cloud.patient.resident.server.vo;

import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

/**
 * @ClassName WechatUserInfoVo
 * @Description {@link} 參考 https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419317853&token=&lang=zh_CN
 * @Author Jun.li0101
 * @Date 2019/3/19 18:59
 * @ModifyDate 2019/3/19 18:59
 * @Version 1.0
 */
@Getter
@Setter
@ToString
public class WechatUserInfoVo extends WechatCommonVo {
    @JSONField(format = "openid")
    private String openid;
    @JSONField(format = "nickname")
    private String nickname;
    @JSONField(format = "sex")
    private Integer sex;
    @JSONField(format = "province")
    private String province;
    @JSONField(format = "city")
    private String city;
    @JSONField(format = "country")
    private String country;
    @JSONField(format = "headimgurl")
    private String headImgurl;
    @JSONField(format = "unionid")
    private String unionid;
    @JSONField(format = "language")
    private String language;

}

  • 微信登錄表情特殊符號處理
    據庫以及JDBC默認的字符集都是utf8,在存儲emoji表情時會報錯:
Incorrect string value: '\xF0\x9F\xA4\xA9' for column 'nickname'

原因是utf8不支持4字節的emoji表情。

具體如下:

utf8與utf8mb4具有相同存儲特性:相同的代碼值,相同的編碼,相同的長度。不過utf8mb4擴展到一個字符最多可有4位元,所以能支持更多的位元集。utf8mb4不只兼容utf8,還能比utf8能展示更新的字符。將編碼改爲utf8mb4外不需要做其他轉換。

爲了要跟國際接軌,原本的utf8編碼在存儲某些國家的文字(或是罕見字)已經不敷使用,因此在mysql5.5.3版以上,可以開始使用4-Byte UTF-8 Unicode的編碼方式。

Mysql查看版本方式:

select version();

Mysql在5.5.3版本之後增加了utf8mb4字符編碼,mb4即most bytes 4。簡單說utf8mb4是utf8的超集並完全兼容utf8,能夠用四個字元存儲更多的字符。

utf8mb4可以向下兼容utf8,而且比utf8可以表示更多的字符。此外,將編碼改爲utf8mb4不需 要其他轉換。

解決辦法:

1.修改mysql配置文件my.cnf,同時將庫表的默認字符集都改爲utf8mb4;

default-character-set=utf8mb4

同時修改項目的JDBC連接配置

spring.datasource.tomcat.init-s-q-l=SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章