使用 Shiro 配合微信小程序或者app登录,做验权

news/2024/7/20 1:34:20 标签: 小程序, 微信

1.用户第一次登录/绑定,通过微信的code拿到用户的openid,存到数据库里
2.用户第二次请求,发起一个微信自动登录请求,同样传入微信的code,后台检验获取openid,检验该openid是否已经存在数据库,如果有就可以自动登录.
3.实现一个自己的MyRealm和MyOpenIdToken,主要为了能够Subject存入openid方便检验

//通过获取到自动登录的openId
        String openid = apiResult.get("openid");
        Subject subject = SecurityUtils.getSubject();
        //使用自定义realm验证openid是否已绑定用户
        WxOpenIdToken wxOpenIdToken =new WxOpenIdToken(openid);
        subject.login(wxOpenIdToken);`
  `MyOpenIdToken`:类似实体类,需要继承`UsernamePasswordToken`
  `MyRealm`:继承`AuthorizingRealm` 真正的验证逻辑在这里处理,

注意 :多个realm需要在shiro配置中配置使用策略,也可以自行百度

 缺点:因为subject中存的是openId所以登录之后还需要额外的去获取用户信息

贴一下我的代码

MyOpenIdToken.java

//MyOpenIdToken
        public class WxOpenIdToken extends UsernamePasswordToken implements Serializable {
        private String openId;
        /**
         *
         */
        private static final long serialVersionUID = 4812793519945855483L;
        @Override
        public Object getPrincipal() {
            return getOpenId();
        }

        @Override
        public Object getCredentials() {
            return "ok";
        }
        public WxOpenIdToken(String openId){
            this.openId=openId;
        }
    }

WxOpenIdRealm.java

public class WxOpenIdRealm extends AuthorizingRealm {
        @Resource
        private SysUserDao sysUserDao;
        @Resource
        private SysMenuDao sysMenuDao;

        /**
         * 授权
         * @param principals
         * @return
         */
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
            //TODO 用户权限列表,普通信息等...
            return info;
        }

        /**
         * 鉴权   openid 判断是否用户是否已经绑定微信
         * @param token
         * @return
         * @throws AuthenticationException
         */
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

            String openid = (String) token.getPrincipal();
                            //sysUserDao.getbyWxaOpenId 根据openid查询是否有已绑定的userid,有就时已绑定
            SysUserEntity exUser = sysUserDao.getbyWxaOpenId(openid);
            if (exUser != null) {
                AuthenticationInfo authcInfo = new SimpleAuthenticationInfo(openid, "ok", this.getClass().getSimpleName());
                return authcInfo;
            } else {
                return null;
            }
        }
    }

ShiroConfig.java 注入两个realm并设置验证策略

@Bean
public UserRealm userRealm(){
    UserRealm userRealm = new UserRealm();
    //账号密码登录使用realm
    return userRealm;
}

@Bean
public WxOpenIdRealm wxCodeRealm(){
    WxOpenIdRealm wxOpenIdRealm = new WxOpenIdRealm();
    //小程序使用openid登录使用的realm
    return wxOpenIdRealm;
}
          /**
     * 系统自带的Realm管理,主要针对多realm
     * */
    @Bean
    public ModularRealmAuthenticator modularRealmAuthenticator() {
        ModularRealmAuthenticator modularRealmAuthenticator = new ModularRealmAuthenticator();
        //只要有一个成功就视为登录成功
        modularRealmAuthenticator.setAuthenticationStrategy(new AtLeastOneSuccessfulStrategy());
        return modularRealmAuthenticator;
    }

不只是微信小程序,同样的还有app登录,手机短信验证码都可以自定义realm验证



由于本人第一次使用微信小程序配合 Shiro 做验权,
发现小程序不能像普通网页那样做验权,
后台 Shiro 根本识别不到小程序客户端的状态

原因
原来是小程序不自带 cookie 的管理,导致 Shiro 下发的 SessionId,
小程序下次请求时,不会带上之前的 SessionId
解决方案
自己手动存储 cookie ,并在所有请求中带上 cookie
这是最简单粗暴的方法之一
(当然,也可以去自定义 Shiro 的 Session 管理,等等其他方法)

第一次登录请求时,保存 cookie

http(post, "/api/wx/login", {
  code,
}).then((response) => {
  wx.setStorageSync("sessionId", response.header["Set-Cookie"]);

  wx.navigateBack();
});

之后发送请求时,都带上 cookie

const http = (method, url, data) => {
  let header;

  // 将存储的 cookie 带上
  if (wx.getStorageSync("sessionId")) {
    header = {
      "content-type": "application/x-www-form-urlencoded",
      cookie: wx.getStorageSync("sessionId"),
    };
  }

  return new Promise((resolve, reject) => {
    wx.request({
      data,
      method,
      url: `${host}${url}`,
      header,
      dataType: "JSON",
      success: (response) => {
        let statusCode = response.statusCode;
      },
      fail: (errors) => {
        wx.showToast({ title: "请求失败", icon: "none" });
        reject(errors);
      },
    });
  });
};

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

相关文章

http的url中参数需要转义的字符

在url中如果参数有包含以下字符需要进行字符转换: 空格 / ? % # & URL 中号表示空格 %2B 空格 URL中的空格可以用号或者编码 %20 / 分隔目录和子目录 %2F ? 分隔实际的U…

urumuqi 网络赛 H skiing DP

题目链接: 一如既往的没有啊 老哥 题目描述: 给以一个有向图, 每个边上有权值, 问你一条通路的最大权值是多少 解题思路: 这道题应该很裸吧,......自己记得以前做过啊, 自己写崩了, 明天早起去看看紫书&am…

Page Object Model (Selenium, Python)

时间 2015-06-15 00:11:56 Qxf2 blog 原文 http://qxf2.com/blog/page-object-model-selenium-python/主题 Selenium PythonWe have come a long way since our post on implementing the Page Object Model - Implementing the Page Object Model (Selenium Python) While …

深入理解let和var的区别(暂时性死区)!!!

首先我们应该知道js引擎在读取js代码时会进行两个步骤: 第一个步骤是解释。第二个步骤是执行。所谓解释就是会先通篇扫描所有的Js代码,然后把所有声明提升到顶端,第二步是执行,执行就是操作一类的。 我们先来看个简单的变量提升案…

多Realm验证策略

前言:多Realm验证,有时候会存在多Realm,不同的角色会有不同的验证逻辑,这个时候会需要多Realm。 首先这里编写两个Realm,并且返回name Realm1:CustomerRealm public class CustomerRealm extends AuthorizingRealm {AutowiredL…

大牛的博客,顶礼膜拜!

hursing的博客 传送门-》 iOS私有API(一) -[UIApplication _cancelAllTouches] 无网不剩(李忠)的博客 传送门-》 Dynamic Tips & Tricks With Objective-C - (译)Objective-C的动态特性 类簇在iOS开发中的应用 Martin Pilking…

CSSs width属性 和offsetwidth属性深入理解

本人菜鸟一枚,趁着奥运期间,一边看奥运,一边学习,最近在慕课网学习前端技术,学习过程中有向很多前辈们博客学习,现在就来分享我的学习所得。 慕课网,导航条菜单的制作,使用javascrip…

Java构造和解析Json数据的两种方法详解二

在www.json.org上公布了很多JAVA下的json构造和解析工具,其中org.json和json-lib比较简单,两者使用上差不多但还是有些区别。下面接着介绍用org.json构造和解析Json数据的方法示例。 用json-lib构造和解析Json数据的方法详解请参见我上一篇博文&#xff…