前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >五. 小程序用户注册登录的实现

五. 小程序用户注册登录的实现

作者头像
用户8988577
发布2022-12-27 15:56:34
8490
发布2022-12-27 15:56:34
举报
文章被收录于专栏:言云纪言云纪

前言

前几期主要针对数据库的设计mybatis的配置以及mybatis逆向生成代码,以及响应体返回信息封装和全局异常拦截的一些配置拦截处理,文章可能枯燥且看不出任何实际效果。本文将结合前几期的配置进行实战操作!

用户登录

微信小程序中自带wx.login接口,请求该接口会返回一个过期时长为五分钟的code。通过开发者的appid和secret将获取到的code发送请求可以取到openid。最后将 openid作为用户唯一标识主键存入数据库完成注册! 点击查看微信开发者appid和secret

前端获取用户登录凭证(code)并请求后端

微信小程序的创建本博客将不叙述,点击跳转微信小程序的创建 在index.js中添加如下代码

代码语言:javascript
复制
  login(){
        // 获取code凭证
        wx.login({
          success(res){
            console.log("wx.login接口得到的数据:",res);
            let code = res.code
            let userinfo = wx.getStorageSync('userinfo')
            userinfo.code = code
            // 将code传入后端
            wx.request({
              url: 'http://127.0.0.1:8080//usercontroller/user',
              method:'post',
              data : userinfo,
              // 后端响应的数据
              success(res){
                console.log("后端返回的数据:",res);
              },
              fail(err){
                console.log("后端请求失败");
              }
            })
          }
        })
  },
  userinfo(){
    let that = this
    wx.getUserProfile({
      desc:'获取用户信息并登录',
      success(res){
        console.log("获取到用户信息:",res.userInfo);
        wx.setStorageSync('userinfo', res.userInfo)
        that.login()
      }
    })
  },

因为官方规定 wx.getUserProfile接口必须处罚点击事件才能调用。所以还需要wxml来调用userinfo方法!

代码语言:javascript
复制
<!--pages/index/index.wxml-->
<button bindtap="userinfo">登录</button>

效果图如下

若提示http://127.0.0.1:8080//usercontroller/userrequest 合法域名列表中,请按下图操作打开不检验合法域名

后端响应并给前端返回Token

后端查询加密后的openid如果存在则直接返回token,如果不存在则新建用户再返回token。

pom依赖注入

代码语言:javascript
复制
        <!--token-->
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.4.0</version>
        </dependency>
        <!-- hutool工具库 -->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.0</version>
        </dependency>
        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <scope>provided</scope>
        </dependency>

controller控制器类

UserContorller

代码语言:javascript
复制
@RestController
@RequestMapping("usercontroller")
public class UserController {
    @Autowired
    private UserService userService;

    @PostMapping("/user")
    public BaseResponse login(@RequestBody Map<String,String> params){
        return userService.login(params);
    }
}

服务层接口类

UserService

代码语言:javascript
复制
public interface UserService {
    public BaseResponse login(Map<String,String> params);
}

服务层接口实现类

UserServiceImpl

代码语言:javascript
复制
@Service("userService")

public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao userDao;
    public BaseResponse login(Map<String,String> params){
        String md5_openid = WeChatUtils.GetOpenid(params.get("code"));
        // 新账号默认创建房间数量为1,上传视频数量5。若不是新账号则用加密后的openid生成token
        User user = User.builder()
                .uImg(params.get("avatarUrl"))
                .uName(params.get("nickName"))
                .openid(md5_openid)
                .createRoom(1)
                .uploadNum(5)
                .build();
//  如果数据库没有这个加密后的openid则注册账号
        if (!userDao.openid(md5_openid)){
            Assert.isTrue(userDao.addUser(user),"创建用户失败,请联系管理员处理");
        }
        Map userMap = new HashMap();
        userMap.put("token",TokenUtils.sign(user));
        return RespGenerator.success(userMap);
    }
}

数据持久层接口类

UserDao

代码语言:javascript
复制
public interface UserDao {
    public Boolean openid(String md5_openId);
    public Boolean addUser(User user);
}

数据持久层接口实现类

代码语言:javascript
复制
@Repository("userDao")
public class UserDaoImpl implements UserDao {
    @Autowired
    private UserMapper userMapper;
    UserExample userExample = new UserExample();
    public Boolean openid(String openId){
        userExample.createCriteria().andOpenidEqualTo(openId);
        return userMapper.selectByExample(userExample).size() < 1 ?false:true;
    }

    public Boolean addUser(User user){
        return userMapper.insert(user) ==1 ?true:false;
    }
}

工具类

WeChatUtils

代码语言:javascript
复制
public class WeChatUtils {
    private static String appid = "wxf9ac121f6797029f";
    private static String secret="78ad8f60d3d686eda0822abfc8c8c8f9";

    public static String getAppid() {
        return appid;
    }

    public static void setAppid(String appid) {
        WeChatUtils.appid = appid;
    }

    public static String getSecret() {
        return secret;
    }

    public static void setSecret(String secret) {
        WeChatUtils.secret = secret;
    }

    public static String GetOpenid(String code){
        String url = "https://api.weixin.qq.com/sns/jscode2session";//指定URL
        Map<String, Object> map = new HashMap<>();//存放参数
        map.put("appid", WeChatUtils.getAppid());
        map.put("secret", WeChatUtils.getSecret());
        map.put("js_code",code);
        map.put("grant_type","authorization_code");
        //发送get请求并接收响应数据
        String result= HttpUtil.createGet(url).form(map).execute().body();
        return SecureUtil.md5(JSONUtil.parseObj(result).get("openid").toString());
    }
}

TokenUtils

代码语言:javascript
复制
@Component
public class TokenUtils {

    //token到期时间10小时
    private static final long EXPIRE_TIME= 10*60*60*1000;
    //密钥盐
    private static final String TOKEN_SECRET="ljdyaishi22jin**3nkjnj??";

    /**
     * 生成token
     * @param user
     * @return
     */
    public static String sign(User user){

        String token=null;
        try {
            Date expireAt=new Date(System.currentTimeMillis()+EXPIRE_TIME);
            token = JWT.create()
                    //发行人
                    .withIssuer("Ocean_Tan")
                    //存放数据
                    .withClaim("md5_openid",user.getOpenid())
                    //过期时间
                    .withExpiresAt(expireAt)
                    .sign(Algorithm.HMAC256(TOKEN_SECRET));
        } catch (IllegalArgumentException|JWTCreationException je) {

        }
        return token;
    }



    @Autowired
    private UserMapper userMapper;
    private static TokenUtils tokenUtils;
    @PostConstruct
    public void inin(){
        tokenUtils = this;
    }

//解密token并判断用户是否存在
    public static Boolean verify(String token){

        try {
            //创建token验证器
            JWTVerifier jwtVerifier=JWT.require(Algorithm.HMAC256(TOKEN_SECRET)).withIssuer("Ocean_Tan").build();
            DecodedJWT decodedJWT=jwtVerifier.verify(token);
            User user = User.builder().openid(decodedJWT.getClaim("md5_openid").asString()).build();
            UserExample userExample = new UserExample();
            userExample.createCriteria().andOpenidEqualTo(user.getOpenid());
            return tokenUtils.userMapper.selectByExample(userExample).size()==1?true:false;
//            System.out.println("过期时间:      " + decodedJWT.getExpiresAt());

        } catch (IllegalArgumentException |JWTVerificationException e) {
            //抛出错误即为验证不通过
//            throw new IllegalArgumentException("未获取到用户信息!请登录!");
            return false;
        }
    }




    //    解密token并获取token用户信息
    public static List<User> tookenList(String token){
        JWTVerifier jwtVerifier=JWT.require(Algorithm.HMAC256(TOKEN_SECRET)).withIssuer("Ocean_Tan").build();
        DecodedJWT decodedJWT=jwtVerifier.verify(token);
        User user = User.builder().openid(decodedJWT.getClaim("md5_openid").asString()).build();
        UserExample userExample = new UserExample();
        userExample.createCriteria().andOpenidEqualTo(user.getOpenid());
        return tokenUtils.userMapper.selectByExample(userExample);
    }


}

效果如下图所示

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-10-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 用户登录
    • 前端获取用户登录凭证(code)并请求后端
      • 后端响应并给前端返回Token
        • pom依赖注入
        • controller控制器类
        • 服务层接口类
        • 服务层接口实现类
        • 数据持久层接口类
        • 数据持久层接口实现类
        • 工具类
    相关产品与服务
    访问管理
    访问管理(Cloud Access Management,CAM)可以帮助您安全、便捷地管理对腾讯云服务和资源的访问。您可以使用CAM创建子用户、用户组和角色,并通过策略控制其访问范围。CAM支持用户和角色SSO能力,您可以根据具体管理场景针对性设置企业内用户和腾讯云的互通能力。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档