网站应用微信登录

网站应用微信登录

官方文档

原理:

网站应用微信登录是基于OAuth2.0协议标准构建的微信OAuth2.0授权登录系统。

获取access_token时序图:网站应用微信登录

网站应用微信登录

实现:(cv区)

<li>
    <a
    id="weixin"
    class="weixin"
    target="_blank"
    href="http://localhost:8150/api/ucenter/wx/login"
    ><i class="iconfont icon-weixin"
    /></a>
</li>
		<!-- JWT -->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.7.0</version>
        </dependency>
        <!--httpclient-->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.1</version>
        </dependency>
        <!--commons-io-->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>
        <!--gson-->
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.2</version>
        </dependency>

需要替换为公司的微信信息:

wx:
  open:
    # 微信开放平台 appid
    app_id: wxed9954c0********
    # 微信开放平台 appsecret
    app_secret: a7482517235173ddb40837**********
    # 微信开放平台 重定向url(****.****需要在微信开放平台配置)
    redirect_url: http://****.****/api/ucenter/wx/callback

JWT原理和JwtUtils.java

/**
 * @author Symon
 * @version 1.0
 * @className WxApiController
 * @date 2021/1/8 14:56
 */
@Controller
@RequestMapping("/api/ucenter/wx")
@CrossOrigin
public class WxApiController {

    @Value("${wx.open.app_id}")
    private String WX_OPEN_APP_ID;

    @Value("${wx.open.appsecret}")
    private String WX_OPEN_APP_SECRET;

    @Value("${wx.open.redirect_url}")
    private String WX_OPEN_REDIRECT_URL;

    @Resource
    private MemberCenterService memberCenterService;

    // 1.生成二维码(官方文档第一步)
    @GetMapping("login")
    public String qrCode() throws Exception{
        String baseUrl = "https://open.weixin.qq.com/connect/qrconnect" +
                "?appid=%s" +
                "&redirect_uri=%s" +
                "&response_type=code" +
                "&scope=snsapi_login" +
                "&state=%s" +
                "#wechat_redirect";
        String state="abcd";
        //对回调路径进行编码
        String encodeUrl = URLEncoder.encode(WX_OPEN_REDIRECT_URL, "utf-8");
        //拼接字符串
        String qrCodeUrl = String.format(baseUrl, WX_OPEN_APP_ID, encodeUrl, state);
        return "redirect:"+qrCodeUrl;
    }


    @GetMapping("callback")
    public String callback(String code,String state) throws Exception{
        //a.通过code+appid+appsecret得到用户的access_token和openid(官方文档第二步)
        String baseAccessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token" +
                "?appid=%s" +
                "&secret=%s" +
                "&code=%s" +
                "&grant_type=authorization_code";
        //拼接字符串
        baseAccessTokenUrl = String.format(baseAccessTokenUrl, WX_OPEN_APP_ID, WX_OPEN_APP_SECRET, code);
        String retVal = HttpClientUtils.get(baseAccessTokenUrl);
        //把json字符串转换为Java对象
        Gson gson = new Gson();
        HashMap infoMap = gson.fromJson(retVal, HashMap.class);
        String accessToken =(String) infoMap.get("access_token");
        String openId =(String) infoMap.get("openid");
        
        //b.根据access_token和openid获取用户信息(官方文档第三步)
        String userInfoUrl = "https://api.weixin.qq.com/sns/userinfo" +
                "?access_token=%s" +
                "&openid=%s";
        //拼接字符串
        userInfoUrl = String.format(userInfoUrl, accessToken, openId);
        String userInfoJson = HttpClientUtils.get(userInfoUrl);
        HashMap userInfoMap = gson.fromJson(userInfoJson, HashMap.class);
        String nickName =(String) userInfoMap.get("nickname");
        String headImgUrl =(String) userInfoMap.get("headimgurl");
        // ......

        //c.拿到用户的个人信息 需要存储起来 存之前先判断该用户是否已经在数据库中有了
        MemberCenter existMember=memberCenterService.queryUserByOpenId(openId);
        if(existMember==null){
            existMember = new MemberCenter();
            existMember.setOpenid(openId);
            existMember.setNickname(nickName);
            existMember.setAvatar(headImgUrl);
            memberCenterService.save(existMember);
        }
        //d.返回一个token给前端
        String token = JwtUtils.geneJsonWebToken(existMember);
        return "redirect:http://127.0.0.1:3000?token="+token;
    }
}

参数说明:

// 1.生成二维码(官方文档第一步)

网站应用微信登录

// a.通过code+appid+appsecret得到用户的access_token和openid(官方文档第二步)

网站应用微信登录

// b.根据access_token和openid获取用户信息(官方文档第三步)

网站应用微信登录

获取用户个人信息(UnionID机制)

请求说明

http请求方式: GET
https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID

参数说明

参数 是否必须 说明
access_token 调用凭证
openid 普通用户的标识,对当前开发者帐号唯一
lang 国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语,默认为zh-CN

返回说明

正确的Json返回结果:

{
"openid":"OPENID",
"nickname":"NICKNAME",
"sex":1,
"province":"PROVINCE",
"city":"CITY",
"country":"COUNTRY",
"headimgurl": "https://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0",
"privilege":[
"PRIVILEGE1",
"PRIVILEGE2"
],
"unionid": " o6_bmasdasdsad6_2sgVt7hMZOPfL"

}
参数 说明
openid 普通用户的标识,对当前开发者帐号唯一
nickname 普通用户昵称
sex 普通用户性别,1为男性,2为女性
province 普通用户个人资料填写的省份
city 普通用户个人资料填写的城市
country 国家,如中国为CN
headimgurl 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空
privilege 用户特权信息,json数组,如微信沃卡用户为(chinaunicom)
unionid 用户统一标识。针对一个微信开放平台帐号下的应用,同一用户的unionid是唯一的。
上一篇:网站开发人员应该知道的61件事


下一篇:identityserver4 自定义验证