springboot微信登录

jovie_Hung

微信登录的优势

目前微信用户数量巨大,用户更希望通过更快更便捷的方式进行登录,而不是传统的账号密码登录。

springboot 接入微信登陆

准备工作

网站应用微信登录是基于OAuth2.0协议标准构建的微信OAuth2.0授权登录系统。 在进行微信OAuth2.0授权登录接入之前,在微信开放平台注册开发者帐号,并拥有一个已审核通过的网站应用,并获得相应的AppID和AppSecret,申请微信登录且通过审核后,可开始接入流程。

说白了就是需要一个AppID和对应的Appsecret

传送门:微信开放平台 (qq.com)

登陆后选一个,这里是网站应用

image-20210930172110597.png

image-20210930172207640.png

顺便再把回调域改一下。

授权流程

D0wkkHSbtC6VUSHX4WsjP5ssg5mdnEmXO8NGVGF34dxS9N1WCcq6wvquR4K_Hcut.png
那我们要做什么呢?

设置一个链接让用户跳转到微信登录扫码界面,然后用户点确认后会带上codestate重定向到我们设置的回调域,这是我们带上code访问微信获得用户的一些基本信息和access_token refresh_token,有了token我们就可以获取用户具体的信息了。这时候我们再设置session就可以让用户登录成功了。
  1. 打开链接

    设置一个链接,格式如下:

    https://open.weixin.qq.com/co...

image-20211001232005609.png

  1. 添加回调域网址接受回调信息

    在用户授权之后,将会重定向到回调域,

    redirect_uri?code=CODE&state=STATE

    这时我们就获取了code,随后访问链接获取 access_token

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

image-20211001232850006.png

正确的返回:

{ 
"access_token":"ACCESS_TOKEN", 
"expires_in":7200, 
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID", 
"scope":"SCOPE",
"unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
}
参数说明
access_token接口调用凭证(我们需要的)
expires_inaccess_token接口调用凭证超时时间,单位(秒),一般是两小时
refresh_token用户刷新access_token
openid授权用户唯一标识,对于当前appid是唯一的
scope用户授权的作用域,使用逗号(,)分隔
unionid当且仅当该网站应用已获得该用户的userinfo授权时,才会出现该字段。
  1. 获取用户详细信息

    继续访问https://api.weixin.qq.com/sns...就可以获取用户的详细信息了

实际操作

1. appId和appSecret的配置

在application.yml的配置:

image-20211021153012697.png

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@Data
@ConfigurationProperties(prefix = "wx")
public class WXConfig {
    private String appId;
    private String appSecret;
}

2. 设置网址

image-20211021170343448.png

3. 设置回调域

导包
<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.13</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.78</version>
</dependency>
工具类
public class CommonUtil {
    private static final int BUFFER_SIZE = 1024 * 8;
    public static String getBody(InputStream inputStream) throws IOException {
        Reader reader = new BufferedReader(new InputStreamReader(inputStream));
        StringWriter writer = new StringWriter();
        int read;
        char[] buf = new char[BUFFER_SIZE];
        while ((read = reader.read(buf)) != -1) {
            writer.write(buf, 0, read);
        }
        return writer.getBuffer().toString();
    }
}
回调域逻辑
@Slf4j
@Controller
public class WXController {
    @Autowired
    private WXConfig wxConfig;
​
    @ResponseBody
    @RequestMapping("/wx/login")
    public String login(HttpServletRequest request) throws IOException {
        String code = request.getParameter("code");
        String state = request.getParameter("state");
        if (code == null){
            log.error("用户取消登录");
        }
        log.info("code = {}", code);
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        String url = "https://api.weixin.qq.com/sns/oauth2/access_token" +
                "?appid=" + wxConfig.getAppId() +
                "&secret=" + wxConfig.getAppSecret() +
                "&code=" + code +
                "&grant_type=authorization_code";
        HttpGet httpGet = new HttpGet(url);
        CloseableHttpResponse response = httpClient.execute(httpGet);
​
        HttpEntity entity = response.getEntity();
        String body = CommonUtil.getBody(entity.getContent());
        log.info(body);
        response.close();
​
        JSONObject bodyJson = JSON.parseObject(body);
        // 这里已经获取了用户的部分信息,可以在数据库中查询,如果已经记录过了,就没有必要进入后面的步骤了
        String accessToken = bodyJson.getString("access_token");
        String openId = bodyJson.getString("openId");
​
        url = "https://api.weixin.qq.com/sns/userinfo" +
                "?access_token=" + accessToken +
                "&openid=" + openId;
        httpGet = new HttpGet(url);
        response = httpClient.execute(httpGet);
        body = CommonUtil.getBody(response.getEntity().getContent());
        bodyJson = JSON.parseObject(body);
        // 获取了用户信息后进行存储
        log.info("the info of user is {}", bodyJson);
        response.close();
        // 登录成功,设置session
        request.getSession().setAttribute("unionId", bodyJson.getString("union_id"));
        return "登录成功";
    }
}

\

阅读 180
4 声望
0 粉丝
0 条评论
你知道吗?

4 声望
0 粉丝
文章目录
宣传栏