• spring boot3登录开发-微信小程序用户登录设计与实现


     

    ⛰️个人主页:     蒾酒

    🔥系列专栏:《spring boot实战》

    🌊山高路远,行路漫漫,终有归途


    目录

    写在前面

    登录流程

    流程解析

    具体实现

    相关代码

    说明

    服务端

    小程序端

    写在最后


    写在前面

    本文介绍了springboot开发微信小程序后端服务中,用户登录功能的设计与实现,坚持看完相信对你有帮助。

    同时欢迎订阅springboot系列专栏,持续分享spring boot的使用经验。

    登录流程

    如图:

    这是微信官方文档中微信小程序登录的流程时序图,我在图中红色序号标注的五步就是完整的微信小程序登录流程。

    流程解析

    1. 小程序端通过wx.login()获取用户登录凭证code。
    2. 小程序将code发送到服务端的登录接口。
    3. 服务端的登录接口使用该code、小程序的AppID和AppSecret向微信服务器发起请求,获取用户的openid。
    4. 服务端拿到openid后,可以根据业务需求生成用户令牌(Token),通常包括用户信息、权限等,并返回给小程序。
    5. 小程序在本地缓存该用户令牌。
    6. 后续小程序发起请求时,在请求头中携带该用户令牌(Token)。
    7. 服务端接收到请求时,验证用户令牌的有效性,确保用户是经过认证和授权的。

    具体实现

    登录接口设计思路

    1. 接收小程序端传递的code参数。
    2. 使用code、小程序的AppID和AppSecret向微信服务器发起请求,获取用户的openid。
    3. 在数据库用户表中查询是否存在该openid。
    4. 如果存在该openid,则使用查询到的用户信息生成令牌(Token)。
    5. 如果不存在该openid,则进行用户注册操作,将新用户信息插入数据库用户表,并生成令牌(Token)。
    6. 返回生成的令牌(Token)给小程序端。

    相关代码

    说明

    下面代码基于jdk17,发请求用的时jdk自带的http工具类,如果你的jdk版本低于11,可以使用okhttp依赖来发请求,然后jwt相关工具类代码在我本专栏的其他文章里面,用到的ORM框架为mybatis-plus整合相关代码也在本专栏。

    服务端

    登录dto

    1. @Data
    2. public class UserLoginDTO {
    3. @NotBlank(message = "code不能为空")
    4. private String code;
    5. private Map userInfo;//用户完善信息
    6. }

    登录返回vo

    1. @Data
    2. @Builder
    3. public class UserLoginVO implements Serializable {
    4. private Long id; //用户id
    5. private String openid;//用户在小程序唯一标识
    6. private String token;//用户登录凭证
    7. }

    获取openid方法

    使用的是jdk17自带的HttpClient,也可以使用okhttp,或者糊涂工具包里面的。

    1. private String getOpenid(String code) {
    2. HttpClient httpClient = HttpClient.newHttpClient();
    3. // 构建请求参数字符串
    4. String params = String.format("appid=%s&secret=%s&js_code=%s&grant_type=%s",
    5. URLEncoder.encode(wxMiniConfig.getAppId(), StandardCharsets.UTF_8),
    6. URLEncoder.encode(wxMiniConfig.getAppSecret(), StandardCharsets.UTF_8),
    7. URLEncoder.encode(code, StandardCharsets.UTF_8),
    8. URLEncoder.encode("authorization_code", StandardCharsets.UTF_8));
    9. // 创建 GET 请求
    10. String url = "https://api.weixin.qq.com/sns/jscode2session?" + params;
    11. HttpRequest httpRequest = HttpRequest.newBuilder()
    12. .uri(URI.create(url))
    13. .build();
    14. try {
    15. // 发送 GET 请求
    16. HttpResponse httpResponse = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());
    17. // 获取响应结果
    18. int statusCode = httpResponse.statusCode();
    19. String responseBody = httpResponse.body();
    20. JSONObject responseJson = JSONObject.parseObject(responseBody);
    21. String openid = responseJson.getString("openid");
    22. // 处理响应结果
    23. System.out.println("状态代码: " + statusCode);
    24. System.out.println("响应正文: " + responseBody);
    25. return openid;
    26. } catch (Exception e) {
    27. log.error("发送请求时出错: {}", e.getMessage());
    28. return null;
    29. }
    30. }

    登录逻辑代码

    在判断出是新用户时,进行注册操作还需要将请求携带过来的userInfo完善信息,用户名,头像等一同封装进User对象再插入到数据库这里我就省略了

    1. @Override
    2. public UserLoginVO login(UserLoginDTO userLoginDTO) {
    3. //获取openid
    4. String openid = getOpenid(userLoginDTO.getCode());
    5. if(StringUtils.isBlank(openid)){
    6. throw new GeneralBusinessException(ResultEnum.USER_OPENID_ERROR); // openid获取失败
    7. }
    8. User user = new LambdaQueryChainWrapper<>(userMapper).eq(User::getOpenid, openid).one();
    9. if(Objects.isNull(user)){
    10. // 用户不存在则注册
    11. user = new User();
    12. //获取完善信息,用户呢称、头像url
    13. userLoginDTO.getUserInfo
    14. //封装信息。。。。。。
    15. //。。。。。。。。。。
    16. user.setOpenid(openid);
    17. // 注册用户
    18. if(!this.save(user)){
    19. throw new GeneralBusinessException(ResultEnum.USER_REGISTER_FAIL); // 用户注册失败
    20. }
    21. }
    22. return UserLoginVO.builder()
    23. .id(user.getUserId())
    24. .openid(user.getOpenid())
    25. .token(jwtUtils.generateToken(Map.of("userId", user.getUserId()), "user"))
    26. .build();
    27. }

    小程序端

    如图点击登录按钮会进行登录(注册)

    wxml:

     <button bindtap="handleLogin">登录button>

    js:

    1. // 点击登录按钮时触发的方法
    2. handleLogin: function() {
    3. // 调用微信登录接口获取 code
    4. wx.login({
    5. success: res => {
    6. const code = res.code;
    7. if (code) {
    8. // 调用微信登录接口获取用户信息
    9. wx.getUserProfile({
    10. desc: '用于完善会员资料',
    11. success: res => {
    12. const userInfo = res.userInfo;
    13. // 将 code 和用户信息发送到后端服务器进行登录验证
    14. wx.request({
    15. url: 'http://localhost:8080/user/login',
    16. method: 'POST',
    17. data: {
    18. code: code,
    19. userInfo: userInfo
    20. },
    21. success: res => {
    22. const { token } = res.data; // 假设后端返回包含 token 的数据
    23. if (token) {
    24. // 登录成功,保存 token到本地存储
    25. wx.setStorageSync('token', token);
    26. // 跳转到主页或其他页面
    27. wx.navigateTo({
    28. url: '/pages/home/home'
    29. });
    30. } else {
    31. // 登录失败,显示提示信息
    32. wx.showToast({
    33. title: '登录失败,请重试',
    34. icon: 'none'
    35. });
    36. }
    37. },
    38. fail: err => {
    39. console.error('登录请求失败', err);
    40. }
    41. });
    42. },
    43. fail: err => {
    44. console.error('获取用户信息失败', err);
    45. }
    46. });
    47. } else {
    48. console.error('获取登录凭证失败', res.errMsg);
    49. }
    50. },
    51. fail: err => {
    52. console.error('调用登录接口失败', err);
    53. }
    54. });
    55. }

    补充:实际开发中不会直接使用wx.request进行登录请求,一般都会进行封装,这里作为演示我就直接使用了,实际发送的post请求,请求体会携带code,和用户昵称、头像路径等信息。

    写在最后

    本文完整的介绍了springboot开发微信小程序服务端中用户登录功能的设计思路,希望对你有帮助。

  • 相关阅读:
    用于校园流浪猫信息记录和分享的小程序源码/微信云开发中大猫谱小程序源码
    js人民币转换大写函数
    私人云盘(自动云同步)
    Elasticsearch进阶篇(三):ik分词器的使用与项目应用
    Git的入门详细教程
    速来查分!2022监理工程师成绩查询入口开启
    前端项目使用钉钉字体
    oracle 12c rac asm使用nfs注意的问题
    mysql8.0.34部署单节点与集群-AB复制(IO与SQL线程不同步解决方法)
    u-blox模块-- UBX protocol(NEO-M9N-00B-00)
  • 原文地址:https://blog.csdn.net/qq_62262918/article/details/136660347