小程序登录-前后台

news/2024/7/20 2:34:48 标签: spring boot, 小程序

1.业务描述

1.小程序用户登录

2.用户入库

3.返回token给小程序用户

4.授权小程序昵称和头像

2.实现流程

参考官方流程图:

3.主要代码

前端:

 

 

后端: 

/**
 * 小程序登录获取接口访问token,主入口
 *
 * @param jsCode 小程序jsCode
 * @return 返回token给前端
 */
@ResponseBody
@GetMapping("code2Session")
@ApiOperation("小程序-code2Session(获取openid)")
public ResponseData code2Session(String jsCode) {
    log.info("小程序用户登录,code2Session(获取openid)");
    String code2SessionUrl = "https://api.weixin.qq.com/sns/jscode2session?appid=" + appid + "&secret=" + secret + "&js_code=" + jsCode + "&grant_type=authorization_code";
    String content = restTemplate.getForEntity(code2SessionUrl, String.class).getBody();
    String openid = JSON.parseObject(content).get("openid").toString();
    String unionid = JSON.parseObject(content).get("unionid").toString();
    if (StrUtil.isEmpty(openid)) {
        return new ErrorResponseData("openid不能为空");
    }
    if (StrUtil.isEmpty(unionid)) {
        return new ErrorResponseData("unionid不能为空");
    }
    Map<String, Object> map = new TreeMap<>();

    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("user_union", unionid);
    User user_union = userService.getOne(queryWrapper);

    QueryWrapper<User> queryWrapper1 = new QueryWrapper<>();
    queryWrapper1.eq("user_mini_wx ", openid);
    User user_mini = userService.getOne(queryWrapper1);

    //判断此用户是否存在数据库中
    if (user_mini == null) {
        User user1;
        log.info("小程序用户登录,当前用户不存在数据库中,进行新建...");
        if (user_union == null) {
            user1 = new User();
            user1.setUserUnion(unionid);
        } else {
            user1 = user_union;
        }
        user1.setUserMiniWx(openid);
        user1.setUserMiniNick(BaseConstant.NICK_DEFAULT);
        user1.setUserMiniHead(BaseConstant.HEAD_DEFAULT);
        user1.setUserSex(1);
        userService.saveOrUpdate(user1);
        log.info("小程序用户登录,用户新建成功!user:{}", user1.toString());
        map.put("token", tokenService.getToken(user1));
        return new SuccessResponseData(map);
    } else {
        log.info("小程序用户登录,当前用户已存在数据库中,直接获取token");
        map.put("token", tokenService.getToken(user_mini));
        return new SuccessResponseData(map);
    }
}
/**
 * 获取小程序头像和昵称进行入库
 *
 * @param nickName  小程序昵称
 * @param avatarUrl 小程序头像
 * @param token     token
 * @return 结果
 */
@ResponseBody
@ApiOperation("小程序-更新头像、昵称")
@PostMapping("/updateNikeAndHead")
public ResponseData updateNikeAndHead(String nickName, String avatarUrl, String token) {
    log.info("小程序更新用户头像和昵称,nickName:{},avatarUrl:{}", nickName, avatarUrl);
    Long userId = TokenUtil.getTokenUserIdMini(token);
    LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
    queryWrapper.eq(User::getUserId, userId);
    User user = userService.getOne(queryWrapper);
    if (user != null) {
        user.setUserMiniNick(nickName);
        user.setUserMiniHead(avatarUrl);
        userService.updateById(user);
        return new SuccessResponseData();
    } else {
        log.error("小程序-更新头像跟昵称,当前token对应的用户不存在,请检查token取值");
        return new ErrorResponseData("用户不存在");
    }
}
/***
 * token 下发
 * @Title: TokenService.java
 * @author zhang pan
 * @date 2022/7/6 23:15
 * @version V1.0
 */
@Slf4j
@Service("TokenService")
public class TokenService {
    public String getToken(User user) {
        Date start = new Date();
        //7天有效时间
        //long currentTime = System.currentTimeMillis() + 60* 60 * 1000 * 24 * 7;
        long currentTime = System.currentTimeMillis() + 60 * 60 * 1000 * 24;
        //long currentTime = System.currentTimeMillis() + 60 * 1000;
        Date end = new Date(currentTime);
        String token = "";
        token = JWT.create()
                .withAudience(user.getUserId().toString()).withIssuedAt(start)
                .withExpiresAt(end)
                .sign(Algorithm.HMAC256("aaaaaa"));
        log.info("getToken..........token:{}", token);
        return token;
    }
}

注意,此处下发的token用JWT形式

4.业务扩展

1.公众号授权登录

2.开放平台unionid机制,用unionid机制,可以关联绑定在同一开放平台下的不同端用户openid,也就是openid不同,但只要帮定于同一开放平台下,则会拿到同一unionid。

/**

* 公众号登录-主入口

*

* @return 接口访问token

*/

@RequestMapping(value = "/token", method = RequestMethod.GET)

@ApiOperation("获取用户token和user信息")

public ModelAndView getToken() {

log.info("公众号用户登录获取token");

String code = request.getParameter("code");

String state = request.getParameter("state");

if (code == null) {

log.error("公众号用户登录,用户禁止未授权");

return new ModelAndView(new RedirectView(null), null);

}

// 获取到了code值,回调没有问题

// 定义地址

String token_url = BaseConstant.WX_ACCESS_TOKEN + appid +

"&secret=" + secret + "&code=" + code + "&grant_type=authorization_code";

//发送请求

ResponseEntity<String> responseEntity = restTemplate.getForEntity(token_url, String.class);

//获取请求结果 json格式字符串

String content = responseEntity.getBody();

//把json字符串装对象

Token token = JSON.parseObject(content, Token.class);

String user_url = BaseConstant.WX_USER_INFO + token.getAccess_token() + "&openid=" + token.getOpenid();

ResponseEntity<String> responseEntity2 = restTemplate.getForEntity(user_url, String.class);

String content1 = new String(responseEntity2.getBody().getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);

WeiXinUser wxUser = JSON.parseObject(content1, WeiXinUser.class);

Map<String, Object> map = new TreeMap<>();

if (wxUser.getOpenid() == null) {

return null;

}

QueryWrapper<User> queryWrapper = new QueryWrapper<>();

queryWrapper.eq("user_wx", wxUser.getOpenid());

User user2 = userService.getOne(queryWrapper);

//判断此用户是否存在数据库中

if (user2 == null) {

log.info("微信公众号用户登录,用户不存在数据库中,新建...");

User user1 = new User();

user1.setUserWx(wxUser.getOpenid());

user1.setUserNick(wxUser.getNickname());

user1.setUserHead(wxUser.getHeadimgurl());

user1.setUserSex(wxUser.getSex());

user1.setUserUnion(wxUser.getUnionid());

userService.save(user1);

log.info("公众号用户登录,用户新建成功!");

//构造返回

map.put("token", tokenService.getToken(user1));

map.put("user", user1.getUserPhone());

return new ModelAndView(new RedirectView(state), map);

} else {

log.info("公众号用户登录,用户存在数据库中,修改");

user2.setUserWx(wxUser.getOpenid());

user2.setUserNick(wxUser.getNickname());

user2.setUserHead(wxUser.getHeadimgurl());

user2.setUserUnion(wxUser.getUnionid());

userService.updateById(user2);

map.put("token", tokenService.getToken(user2));

map.put("user", user2.getUserPhone());

return new ModelAndView(new RedirectView(state), map);

}

}


http://www.niftyadmin.cn/n/172459.html

相关文章

ThingsBoard开源物联网平台智慧农业实例快速部署教程(Ubuntu、CentOS适用)

ThingsBoard部署教程文档 文章目录ThingsBoard部署教程文档1. JDK环境安装2. 安装thingsBoard2.1 ThingsBoard软件包安装2.2 PostgreSQL安装2.3 PostgreSQL初始化配置3. 修改ThingsBord的配置4. 运行安装脚本测试5. 访问测试6. 导入一个仪表盘库6.1 导出仪表盘并导入自己的项目…

【CSS】浮动 ② ( 浮动语法简介 | 文字环绕效果 | 左浮动 | 右浮动 )

文章目录一、浮动语法简介1、语法说明2、没有浮动的效果3、左浮动的效果4、右浮动的效果5、右浮动 外边距效果二、完整代码示例一、浮动语法简介 1、语法说明 为 元素 设置了 浮动 CSS 属性 , 可以实现 : 元素标签 不再受 标准流 控制 ; ( 块级元素 , 行内元素 , 行内块元素 …

leetcode使用vscode调试C++代码

leetcode使用vscode调试C代码 这里记录一下大体思路吧&#xff0c;关于细节配置放上别的博主的链接&#xff0c;他们讲的更好 vscode只是编辑器&#xff0c;相当于记事本&#xff0c;需要下载minGW提供的编译器和调试器 官方介绍&#xff1a; C/C拓展不包括编译器或调试器&…

【数据结构与算法】用栈实现队列

文章目录&#x1f63b;前言如何用栈实现队列&#xff1f;用栈实现队列整体的实现代码&#x1f63c;写在最后&#x1f63b;前言 &#x1f61d;上一章我们用队列实现了一个栈&#xff08;-> 传送门 <-&#xff09;&#xff0c;而这一章就带大家用栈实现一个队列。 &#x1…

一起学 WebGL:坐标系

大家好&#xff0c;我是前端西瓜哥&#xff0c;今天我们来学习 WebGL。 WebGL 的世界坐标系是三维的。默认使用笛卡尔坐标系的右手坐标系&#xff0c;满足右手定则&#xff0c;即 x 轴向右&#xff0c;y 轴向上&#xff0c;z 轴向着观察者&#xff0c;原点位于画布中心。 然后…

python 安装包相关命令

查看匹配的版本(大小写敏感)pip -V查询已经安装了的包&#xff0c;并可以显示相应的版本&#xff1a;pip list升级pip版本直接输入你电脑上的提示信息中的命令WARNING: You areusing pip version 21.2.4; however, version 23.0.1 is available.You should considerupgrading v…

DPDK系列之九虚拟化vhost

一、virtio-net的发展 virtio-net的驱动最初从后端再到内核怸的vhost-net&#xff0c;发展到用户态的vhost-user&#xff0c;其实就是对效率和扩展性的一个不断演进的过程。在前面提到过&#xff0c;提高云环境下的网络数据传输速度&#xff0c;一个是减少传播路径&#xff0c…

信息收集-查看源代码三操作查看约定成俗的文件

1、查看源码三操作重现过程 注意&#xff1a;测试靶场如&#xff1a;https://jupiter.challenges.picoctf.org/problem/41511/ 1、火狐浏览器访问该靶场&#xff0c;F12--》查看器&#xff0c;可以查看html页面内容&#xff0c;发现如下flag。 2、火狐浏览器访问该靶场&#…