WeChatApiController.java 5.6 KB
package com.skua.modules.system.controller;

import cn.hutool.http.HttpUtil;
import com.google.gson.Gson;
import com.skua.core.api.vo.Result;
import com.skua.modules.system.util.ConstantPropertiesUtil;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import com.skua.modules.system.vo.Member;
import org.springframework.web.bind.annotation.RestController;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@RequestMapping("/wechat")
@Api(tags = "微信相关接口")
@RestController
@Slf4j
public class WeChatApiController {

    /**
     * 生成微信扫描二维码
     * @return
     */
    @GetMapping("login")
    public Result<Map<String,Object>> getWxCode() {
        Result<Map<String,Object>> result = new Result<>();
        Map<String,Object> map = new HashMap<>();
        // 回调地址
        String redirectUrl = ConstantPropertiesUtil.WX_OPEN_REDIRECT_URL; //获取业务服务器重定向地址
        try {
            redirectUrl = URLEncoder.encode(redirectUrl, "UTF-8"); //url编码
        } catch (UnsupportedEncodingException e) {
        }
        // 防止csrf攻击(跨站请求伪造攻击)
        String state = UUID.randomUUID().toString().replace("-", "");//一般情况下会使用一个随机数
        // 微信开放平台授权baseUrl
        String qrcodeUrl = "https://open.weixin.qq.com/connect/qrconnect" +
                "?appid=" + ConstantPropertiesUtil.WX_OPEN_APP_ID +
                "&redirect_uri=" + redirectUrl +
                "&response_type=code" +
                "&scope=snsapi_login" +
                "&state=" + state;
        // 采用redis等进行缓存state 使用sessionId为key 30分钟后过期,可配置
        //键:"wechar-open-state-" + httpServletRequest.getSession().getId()
        //值:satte
        //过期时间:30分钟
        String get = HttpUtil.get(qrcodeUrl);
        int index = get.indexOf("connect/qrcode/");
        if(index > 0){
            //截取_之前字符串
            String qrUrl = get.substring(get.indexOf("connect/qrcode/"),get.length()).substring(15,31);
            map.put("qrUrl","https://open.weixin.qq.com/connect/qrcode/"+qrUrl);
            map.put("state", state);
            map.put("code","");
            result.setResult(map);
            result.setSuccess(true);
        }else{
            map.put("qrUrl","");
            map.put("state", "");
            map.put("code","");
            result.setResult(map);
            result.setSuccess(false);
        }
        return result;
    }


    /**
     * 用户扫描授权同意的回调
     */
    /**
     * @param code
     * @param state
     * @return
     */
    @GetMapping("callback")
    public String callback(String code, String state){
        //得到授权临时票据code
        System.out.println(code);
        System.out.println(state);

        //从redis中将state获取出来,和当前传入的state作比较
        //如果一致则放行,如果不一致则抛出异常:非法访问

        //向认证服务器发送请求换取access_token
        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 = null;
        try {
            result = HttpUtil.get(accessTokenUrl);
            System.out.println("accessToken=============" + result);
        } catch (Exception e) {
        }

        //解析json字符串
        Gson gson = new Gson();
        HashMap map = gson.fromJson(result, HashMap.class);
        String accessToken = (String)map.get("access_token");
        String openid = (String)map.get("openid");

        //查询数据库当前用用户是否曾经使用过微信登录
//        Member member = memberService.getByOpenid(openid);
        Member member = null;
        if(member == null){
            System.out.println("新用户注册");

            //访问微信的资源服务器,获取用户信息
            String baseUserInfoUrl = "https://api.weixin.qq.com/sns/userinfo" +
                    "?access_token=%s" +
                    "&openid=%s";
            String userInfoUrl = String.format(baseUserInfoUrl, accessToken, openid);
            String resultUserInfo = null;
            try {
                resultUserInfo = HttpUtil.get(userInfoUrl);
                System.out.println("resultUserInfo==========" + resultUserInfo);
            } catch (Exception e) {
            }

            //解析json
            HashMap<String, Object> mapUserInfo = gson.fromJson(resultUserInfo, HashMap.class);
            String nickname = (String)mapUserInfo.get("nickname");
            String headimgurl = (String)mapUserInfo.get("headimgurl");

            //向数据库中插入一条记录
            member = new Member();
            member.setNickname(nickname);
            member.setOpenid(openid);
            member.setAvatar(headimgurl);
//            memberService.save(member);
            System.out.println("插入数据库");
        }

        //TODO 登录
        return "redirect:http://localhost:3000";
    }

}