PC端网站-微信扫码登录+shiro权限框架免密登录

文章原创,转载请注明原文链接

一、准备工作:

1. 一个认证的微信《开放平台》账号。

2. 在这个账号下添加网站【已审核通过的网站应用】。

3.一个测试用的域名。我测试的时候是在腾讯云买的,1¥/月,只需要实名认证,不需要备案。这个域名只能本机使用。

备注:账号认证and网站认证都需要公司提供,需要软妹币和公司的章子。

二、调微信接口:

    微信官方文档即可。https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419316505&token=733b43ce86585debf2012bcf0f1c3d429094f3fe&lang=zh_CN。

微信扫码的顺序是:生成二维码-》用户确认-》跳转url,携带code-》用code换openId-》获取用户信息(unionid,nickname)

微信接口的准备参数:AppID和AppSecret。当配置好网站应用时可得到这两个参数。

 

我使用的是js嵌码的方式。通过实例化WxLogin对象,会在页面初始化的时候获取到code和随机数state,然后执行回调url,跳转到redirect_uri页面。【redirect_uri必须是域名访问,且域名必须是网站应用配置的域名】。
页面获取到code,传到后端接口中。接口通过code换取用户的唯一标识。openId,access_token。进一步获取微信用户的unionid,nickname,之类的用户信息。

接口的调用没什么可说的。繁琐的是前期的准备工作。

 

接下来获取到用户信息(唯一标识等)。后端可以判断此用户存不存在,好进行之后的操作,如果是系统有效用户,则需要通过shiro登录验证。

shiro登录验证:(账号密码登录)

boolean rememberMe = false;
String host = StringUtils.getRemoteAddr((HttpServletRequest)request);
String captcha ="";
boolean mobile = false;
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(username, password.toCharArray(), 
rememberMe, host, captcha, mobile);
subject.login(token);
UsernamePasswordToken 是继承自org.apache.shiro.authc.UsernamePasswordToken(shiro的账号密码令牌)

最重要的是subject.login(token),登录验证。想要免密登录需要两步:

1、需要一个没有密码的token

2、在登录验证的时候跳过密码验证。

 

首先第一步:

因为代码原有的UsernamePasswordToken,所以只需要新增一个无密码的构造方法。再新加一个属性,用来密码校验的时候判断这是免密登录。

/**
 * 用户和密码(包含验证码)令牌类
 */
public class UsernamePasswordToken extends org.apache.shiro.authc.UsernamePasswordToken {
 
    private static final long serialVersionUID = 1L;
 
    private String captcha;
    private boolean mobileLogin;
    private String loginType; //登录方式 微信
 
    public UsernamePasswordToken() {
        super();
    }
    /**
     * 账号密码登录
     */
    public UsernamePasswordToken(String username, char[] password,
            boolean rememberMe, String host, String captcha, boolean mobileLogin) {
        super(username, password, rememberMe, host);
        this.captcha = captcha;
        this.mobileLogin = mobileLogin;
        this.loginType = DictCodes.LOGIN_TYPE_PC;
    }
 
    public UsernamePasswordToken(String username) {
        super(username, "", false, null);
        this.loginType = DictCodes.LOGIN_TYPE_WECHAT;
    }
 
    public String getCaptcha() {
        return captcha;
    }
 
    public void setCaptcha(String captcha) {
        this.captcha = captcha;
    }
 
    public boolean isMobileLogin() {
        return mobileLogin;
    }
 
    public String getLoginType() {
        return loginType;
    }
 
    public void setLoginType(String loginType) {
        this.loginType = loginType;
    }
}
静态变量就是标识,自己定义即可。

第二步:

想要跳过密码校验,需要重写shiro的密码校验方法。
首先找到shiro的密码校验方法:

org.apache.shiro.authc.credential.HashedCredentialsMatcher.doCredentialsMatch()
【shiro代码,jar包】

public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
        Object tokenHashedCredentials = this.hashProvidedCredentials(token, info);
        Object accountCredentials = this.getCredentials(info);
        return this.equals(tokenHashedCredentials, accountCredentials);
    }
我们继承这个类,并重写doCredentialsMatch()

public class MyHashedCredentialsMatcher extends HashedCredentialsMatcher {
 
    public MyHashedCredentialsMatcher() {
    }
 
    public MyHashedCredentialsMatcher(String hashAlgorithmName) {
        super(hashAlgorithmName);
    }
 
    @Override
    public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
        UsernamePasswordToken uToken = (UsernamePasswordToken) token;
        if (uToken.getLoginType().equals(DictCodes.LOGIN_TYPE_PC)) {
            return super.doCredentialsMatch(token, info);
        } else {
            return true;
        }
    }
}
在自定义密码校验规则处,将对象实例化或强转为我们免密的类MyHashedCredentialsMatcher【这部分代码不可复用】

    /**
     * 设定密码校验的Hash算法与迭代次数
     */
    @PostConstruct
    public void initCredentialsMatcher() {
        MyHashedCredentialsMatcher matcher = new MyHashedCredentialsMatcher(SystemService.HASH_ALGORITHM);
        matcher.setHashIterations(SystemService.HASH_INTERATIONS);
        setCredentialsMatcher(matcher);
    }
免密登录就配置好了。

这部分代码是建立在完善的shiro框架,账号密码登录已投入使用的基础上进行免密登录。若想搭建shiro请参考其他文档。

shiro登录验证:(无密码登录)


Subject subject = SecurityUtils.getSubject();
// 免密登录
UsernamePasswordToken token = new UsernamePasswordToken(username);
subject.login(token);
 

文章原创,转载请注明原文链接
--------------------- 
作者:BAT_number 
来源:CSDN 
原文:https://blog.csdn.net/BAT_number/article/details/83054491 
版权声明:本文为博主原创文章,转载请附上博文链接!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值