微信小程序实现token登录

这篇具有很好参考价值的文章主要介绍了微信小程序实现token登录。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

微信小程序实现token登录

微信小程序登录流程

微信小程序登录token,微信小程序,小程序,java

前端先调用wx.login()接口获取code,再把code发个后端

login() {
  wx.login({
    success: (res) => {
      wx.request({
          url:"/login",
          method:"POST",
          data:{
              code:res
          },
          dataType:'json'
      })
    },
  })
}

后端采用是SpringSecurity+jwt+redis

@RestController
public class LoginController {

    @Autowired
    LoginService loginService;

    @PostMapping("/login")
    public R<Map<String,Object>> login(@RequestBody Map<String, String> params) {
        String code = params.get("code");
        if (StringUtils.isBlank(code)) {
            throw new ValidateException("code不能为空");
        }

        return loginService.login(code);
    }
}

后端接收code之后再发送http到微信官方获得openid

@Component
@ConfigurationProperties(prefix = "wx")
@Data
public class WxLogin {
    private  String appid;
    private  String secret;
    private  String grant_type;
    private  String wxurl;


    public String getOpenId(String code) throws IOException, URISyntaxException {
        URL url = new URL(wxurl);
        URI uri = new URIBuilder().setScheme(url.getProtocol())
                .setHost(url.getHost())
                .setPort(url.getPort())
                .setPath(url.getPath())
                .setParameters(
                        new BasicNameValuePair("appid",appid),
                        new BasicNameValuePair("secret",secret),
                        new BasicNameValuePair("js_code",code),
                        new BasicNameValuePair("grant_type",grant_type)
                ).build();

        HttpGet httpGet = new HttpGet(uri);

        CloseableHttpClient httpClient = HttpClientBuilder.create().build();

        // 配置信息
        RequestConfig requestConfig = RequestConfig.custom()
                // 设置连接超时时间(单位毫秒)
                .setConnectTimeout(5000)
                // 设置请求超时时间(单位毫秒)
                .setConnectionRequestTimeout(5000)
                // socket读写超时时间(单位毫秒)
                .setSocketTimeout(5000)
                // 设置是否允许重定向(默认为true)
                .setRedirectsEnabled(true).build();

        httpGet.setConfig(requestConfig);

        //响应
        CloseableHttpResponse response = httpClient.execute(httpGet);

        // 从响应模型中获取响应实体
        String openId = null;
        try {
            HttpEntity responseEntity = response.getEntity();
//            System.out.println("响应状态为:" + response.getStatusLine());
            if (StringUtils.isNull(responseEntity)) {
                throw new WxLoginException("响应体为空");
            }
//            System.out.println("响应内容长度为:" + responseEntity.getContentLength());
//            System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));
            JSONObject json = JSON.parseObject(EntityUtils.toString(responseEntity));
            openId = json.getString("openid");
            if (StringUtils.isNull(openId)) {
                throw new WxLoginException("openid重复使用");
            }
        } finally {
            httpClient.close();
            response.close();
        }

        return openId;

    }
}

通过opid查询数据库进行登录注册。

springsecurity登录流程

微信小程序登录token,微信小程序,小程序,java

@Service
public class LoginServiceImpl implements LoginService {

    @Autowired
    private WxLogin wxLogin;

    @Autowired
    private UserService userService;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private TokenService tokenService;

    @Override
    public R<Map<String, Object>> login(String code) {
        //得到openID
        String openId = null;
        try {
            openId = wxLogin.getOpenId(code);
        } catch (IOException | URISyntaxException e) {
            e.printStackTrace();
            return R.fail(HttpStatus.ERROR,"服务器请求异常");
        }
        //查询数据库是否存在openID
        boolean exist = true;
        //先查缓存再查数据库
        LoginUser loginUser = redisCache.getCacheObject(RedisCacheKeys.USERINFO_KEY + openId);
        if (StringUtils.isNull(loginUser)) {
            loginUser = new LoginUser();
        }
        if (StringUtils.isNull(loginUser.getUser())) {
            LambdaQueryWrapper<User> uqw = new LambdaQueryWrapper<>();
            uqw.eq(User::getOpenid,openId);
            User user = userService.getOne(uqw);
            if (StringUtils.isNull(user)) {
                exist = false;
            } else {
                loginUser.setUser(user);
                redisCache.setCacheObject(RedisCacheKeys.USERINFO_KEY+openId, loginUser);
            }
        }
        //不存在就注册,再登录
        if(!exist) {
            register(openId);
        }
        //springsecurity进行登录,存在就登录
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(openId, "null");
        Authentication authenticate = authenticationManager.authenticate(authenticationToken);

        if (StringUtils.isNull(authenticate)) {
            throw new UsernameNotFoundException("用户名不出在!");
        }

        //封装
        LoginUser user = (LoginUser) authenticate.getPrincipal();

        //生成token
        String token = tokenService.createToken(user);
        UserInfoVo userInfo = BeanUtils.copyBean(loginUser.getUser(),UserInfoVo.class);

        HashMap<String, Object> res = new HashMap<String, Object>();
        res.put("token",token);
        res.put("userInfo",userInfo);
        return R.ok(res);
    }

    @Override
    public void register(String openId) {
        //
        User user = new User();
        user.setOpenid(openId);
        userService.save(user);
    }
}
token生成
@Component
public class TokenService
{
    // 令牌自定义标识
    @Value("${token.header}")
    private String header;

    // 令牌秘钥
    @Value("${token.secret}")
    private String secret;

    // 令牌有效期(默认30分钟)
    @Value("${token.expireTime}")
    private int expireTime;

    protected static final long MILLIS_SECOND = 1000;

    protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND;

    protected static final long MILLIS_HOURS = 60 * MILLIS_MINUTE;

    private static final Long MILLIS_MINUTE_TEN = 60 * 60 * 1000L;

    @Autowired
    private RedisCache redisCache;

    /**
     * 获取用户身份信息
     *
     * @return 用户信息
     */
    public LoginUser getLoginUser(HttpServletRequest request)
    {
        // 获取请求携带的令牌
        String token = getToken(request);
        if (StringUtils.isNotEmpty(token))
        {
            try
            {
                Claims claims = parseToken(token);
                // 解析对应的权限以及用户信息
                String openid = (String) claims.get(Constants.LOGIN_USER_KEY);
                String userKey = getTokenKey(openid);
                return redisCache.getCacheObject(userKey);
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
        return null;
    }


    /**
     * 删除用户身份信息
     */
    public void delLoginUser(String token)
    {
        if (StringUtils.isNotEmpty(token))
        {
            String userKey = getTokenKey(token);
            redisCache.deleteObject(userKey);
        }
    }

    /**
     * 创建令牌
     *
     * @param loginUser 用户信息
     * @return 令牌
     */
    public String createToken(LoginUser loginUser)
    {
        refreshToken(loginUser);

        Map<String, Object> claims = new HashMap<>();
        claims.put(Constants.LOGIN_USER_KEY, loginUser.getUser().getOpenid());
        return createToken(claims);
    }

    /**
     * 验证令牌有效期,相差不足一个小时,自动刷新缓存
     *
     * @param loginUser
     * @return 令牌
     */
    public void verifyToken(LoginUser loginUser)
    {
        long expireTime = loginUser.getExpireTime();
        long currentTime = System.currentTimeMillis();
        if (expireTime - currentTime <= MILLIS_MINUTE_TEN)
        {
            refreshToken(loginUser);
        }
    }

    /**
     * 刷新令牌有效期
     *
     * @param loginUser 登录信息
     */
    public void refreshToken(LoginUser loginUser)
    {
        loginUser.setLoginTime(System.currentTimeMillis());
        loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_HOURS);
        // 根据uuid将loginUser缓存
        String userKey = getTokenKey(loginUser.getUser().getOpenid());
        redisCache.setCacheObject(userKey, loginUser,
                expireTime,TimeUnit.HOURS);
    }



    /**
     * 从数据声明生成令牌
     *
     * @param claims 数据声明
     * @return 令牌
     */
    private String createToken(Map<String, Object> claims)
    {
        return Jwts.builder()
                .setClaims(claims)
                .signWith(SignatureAlgorithm.HS512, secret).compact();
    }

    /**
     * 从令牌中获取数据声明
     *
     * @param token 令牌
     * @return 数据声明
     */
    private Claims parseToken(String token)
    {
        return Jwts.parser()
                .setSigningKey(secret)
                .parseClaimsJws(token)
                .getBody();
    }

    /**
     * 从令牌中获取用户名
     *
     * @param token 令牌
     * @return 用户名
     */
    public String getUsernameFromToken(String token)
    {
        Claims claims = parseToken(token);
        return claims.getSubject();
    }

    /**
     * 获取请求token
     *
     * @param request
     * @return token
     */
    private String getToken(HttpServletRequest request)
    {
        return request.getHeader(header);
    }

    private String getTokenKey(String openId)
    {
        return RedisCacheKeys.USERINFO_KEY + openId;
    }
}

    

完整流程图

微信小程序登录token,微信小程序,小程序,java

**
* 获取请求token
*
* @param request
* @return token
*/
private String getToken(HttpServletRequest request)
{
return request.getHeader(header);
}

private String getTokenKey(String openId)
{
    return RedisCacheKeys.USERINFO_KEY + openId;
}

}文章来源地址https://www.toymoban.com/news/detail-563195.html


完整流程图

[外链图片转存中...(img-KPgnRjWY-1678029553423)]

到了这里,关于微信小程序实现token登录的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java后台实现网站微信扫码登录功能,获取用户openid,及微信用户信息(小程序码方案),关联微信小程序(个人主体小程序也可以)

    目录 前言 下面展示操作流程 注册微信小程序 通过后台获取小程序码 前端处理 时序图理解 方案实现步骤 前言 很多业务场景之下我们需要实现  微信扫码登录  的需求,如: 同步网站与小程序的用户数据 。 需要获取用户微信相关基本信息,如头像、id等 实例:小程序上的

    2024年02月02日
    浏览(55)
  • Java 微信小程序登录

    服务端微信小程序登录流程.

    2024年02月11日
    浏览(37)
  • 【微信小程序】实现微信小程序登录(附源码)

    通过 点击登录按钮 , 调用微信接口 wx.getUserProfile拿到微信的个人信息,先 检查是否之前已经登录 ,若没登录则将拿到的个人信息调用后台的接口,把个人信息传给后台, 登录成功之后 把相关信息存储在app.globalData中共享给全局使用 (这里使用微信云开发作为后台,提前建

    2024年02月11日
    浏览(51)
  • node微信小程序登录实现登录

    node微信小程序登录实现登录 好久不见兄弟们这段时间比较忙 需要使用到的模块 废话少说直接上可cv(bai piao)代码 下面展示我的完整代码

    2024年02月09日
    浏览(47)
  • 微信小程序,如何实现登录

    业务流程: 1:首先需要一个按钮触发事件 2:调用微信小程序的登录接口wx.login,拿到code 3:调用微信小程序的获取用户信息的接口wx.getUserProfile,拿到用户的个人信息(包括用的昵称以及头像) 4:拿到的个人信息调用后台的接口,八个人信息传给后台,登陆成功并把相关喜喜

    2024年02月03日
    浏览(39)
  • 微信小程序 如何实现登录

    业务流程: 1:首先需要一个按钮触发事件 2:调用微信小程序的登录接口 wx.login ,拿到code 3:调用微信小程序的获取用户信息的接口 wx.getUserProfile ,拿到用户的个人信息 4: 拿到的个人信息调用后台的接口,把个人信息传给后台,登录成功并把相关信息存储在本地的缓存中

    2024年02月09日
    浏览(80)
  • Java - 微信小程序授权手机号登录

            最近做了一个关于商城的项目,B端选用若依的开源框架,C端还是vue前后端分离。其中C端主要是小程序的形式,所以想着来总结一下对接微信小程序登录中Java部分遇到的坑即代码分享! 废话不多说,直接上代码! 1、controller 层代码          入参我这边是直接使用

    2024年02月04日
    浏览(50)
  • 微信小程序 + Java + Mysql(登录 Demo)

    目录 一、开发前准备 二、设计登录页面(小程序) 三、创建 Maven 项目 四、创建数据库与数据表 五、后台代码(Java Servlet) 六、运行 七、总结 建议  1、注册一个微信开发者账号:https://open.weixin.qq.com (略)  2、开发工具:idea、Mysql、微信开发者工具  3、应用技术:Ja

    2024年02月03日
    浏览(35)
  • 微信小程序实现简单登录界面和登录功能

    客户端开发和学习过程中,登录功能是一个很常见的场景。本文将介绍,微信小程序开发过程中是如何实现登录界面和登录功能的。 话不多说,直接上代码。 (1)index.js文件,代码如下: (2)index.wxml文件,代码如下: (3)index.wxss文件,代码如下: 运行结果如下: 本文介绍了微信

    2024年02月12日
    浏览(92)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包