记录:Java实现微信扫码登录

准备工作

微信开放平台进行开发者资质认证(只有企业才能认证),然后得到 appidapp_secret,然后配置’redirect_url’也就是扫码成功后跳转的地址

开始

根据上面的appid等信息跳转扫码页面,返回一个 code类似于验证码,根据 code 访问另一个固定地址获取openidaccsess_token,然后再根据 openid和access_token 访问另一个固定地址获取用户信息

1. 将上面的信息配置到 application.yml

wx:
  open:
    appid: 你的appid # 微信开放平台 appid
    appsecret: 你的appsecret # 微信开放平台 appsecret
    redirecturl: 重定向url # 微信开放平台 重定向url(需要在微信开放平台配置)

2. 为了方便管理,创建一个常量类

@Component
public class ConstantProperties implements InitializingBean {
    @Value("${wx.open.appid}")
    private String appId;

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

    @Value("${wx.open.redirecturl}")
    private String redirectUrl;

    public static String WX_OPEN_APP_ID;
    public static String WX_OPEN_APP_SECRET;
    public static String WX_OPEN_REDIRECT_URL;
    @Override
    public void afterPropertiesSet() throws Exception {
        WX_OPEN_APP_ID = appId;
        WX_OPEN_APP_SECRET = appSecret;
        WX_OPEN_REDIRECT_URL = redirectUrl;
    }
}

3. 编写接口

因为要跳转到微信扫码的界面,所以必须标记 @Controller 而不是 @RestController

3.1 二维码页面

@GetMapping("login")
    public String genQrConnect() {
        // 微信开放平台授权baseUrl,固定的地址
        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 redirectUrl = ConstantPropertiesUtil.WX_OPEN_REDIRECT_URL; //获取业务服务器重定向地址
        try {
            redirectUrl = URLEncoder.encode(redirectUrl, "UTF-8"); //url编码
        } catch (UnsupportedEncodingException e) {
            throw new GolbalException( e.getMessage());
        }
        // 防止csrf攻击(跨站请求伪造攻击)
        String state = UUID.randomUUID().toString().replaceAll("-", "");//一般情况下会使用一个随机数
        //生成qrcodeUrl
        String qrcodeUrl = String.format(
                baseUrl,
                ConstantPropertiesUtil.WX_OPEN_APP_ID,
                redirectUrl,
                state);
        return "redirect:" + qrcodeUrl;
    }

3.2 扫码成功后的 callback接口(登录逻辑在这里实现)

    @GetMapping("/callback")
    public String callback(String code,String state){
        // 获取code值,拿着 code 请求微信固定地址,得到 accsess_token 和 openId
        String baseAccessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token" +
        "?appid=%s" +
        "&secret=%s" +
        "&code=%s" +
        "&grant_type=authorization_code";
        String accessTokenUrl = String.format(baseAccessTokenUrl,
                ConstantPropertiesUtil.WX_OPEN_APP_ID,
                ConstantPropertiesUtil.WX_OPEN_APP_SECRET,
                code);
        String result = restTemplate.getForObject(accessTokenUrl,String.class);
        HashMap<String,String> hashMap = JSON.parseObject(result, HashMap.class);
        String accessToken =  hashMap.get("access_token");
        String openid =  hashMap.get("openid");
        log.info("token:{},openid:{}",accessToken,openid);

        // 查询数据库当前用用户是否曾经使用过微信登录
        User user = userService.getByOpenId(openid);
        if (user == null){
            log.info("新用户注册");
            //访问微信的资源服务器,获取用户信息
            String baseUserInfoUrl = "https://api.weixin.qq.com/sns/userinfo" +
            "?access_token=%s" +
            "&openid=%s";
            String userInfoUrl = String.format(baseUserInfoUrl, accessToken, openid);
            String resultUserInfo = null;
            resultUserInfo = restTemplate.getForObject(userInfoUrl,String.class);
            log.info("用户信息:{}",resultUserInfo);
            //解析json
            HashMap<String,Object> mapUserInfo = JSON.parseObject(resultUserInfo, HashMap.class);
            // 获取微信名
            String nickname = (String)mapUserInfo.get("nickname");
            // 获取头像
            String headimgurl = (String)mapUserInfo.get("headimgurl");
            //向数据库中插入一条记录
            user = new User();
            user.setNickname(nickname);
            user.setOpenid(openid);
            user.setAvatar(headimgurl);
            userService.save(member);
        }
        // @TODO 登录逻辑,生成token等
        return "redirect:http://localhost:3000";
    }

你可能感兴趣的:(java,微信,开发语言)