zoukankan      html  css  js  c++  java
  • litemall源码阅读4.02 后台的登录验证与个人理解

    核心文件是src/main/java/org/linlinjava/litemall/admin/web/AdminAuthController.java

    进入文件,找到登录验证请求的/admin/auth/login映射。

    这里面主要包含了shrio安全框架的知识。我在这里卡了很长时间。

    另外:springboot开启跨域这个知识点比较固定,就没写日志。

    @RestController
    @RequestMapping("/admin/auth")
    @Validated
    public class AdminAuthController {
    private final Log logger = LogFactory.getLog(AdminAuthController.class);  //控制台打印日志类

    @Autowired
    private LitemallAdminService adminService;  //获取管理员帐号,密码,头像等信息。
    @Autowired
    private LitemallRoleService roleService;  //获取角色。
    @Autowired
    private LitemallPermissionService permissionService;  //获取每个角色的权限。
    @Autowired
    private LogHelper logHelper;  //关于LogHelper。其实就是操作数据库的一个service。

    /*
    * { username : value, password : value }
    */
    @PostMapping("/login")
    public Object login(@RequestBody String body, HttpServletRequest request) {
    String username = JacksonUtil.parseString(body, "username");
    String password = JacksonUtil.parseString(body, "password");

    if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
    return ResponseUtil.badArgument();
    }

    Subject currentUser = SecurityUtils.getSubject();
    try {
          //构建对象进行密码验证,该函数执行会调用src/main/java/org/linlinjava/litemall/admin/shiro/AdminAuthorizingRealm.java
          //中的doGetAuthenticationInfo函数。
                currentUser.login(new UsernamePasswordToken(username, password));  
    } catch (UnknownAccountException uae) {
    logHelper.logAuthFail("登录", "用户帐号或密码不正确");
    return ResponseUtil.fail(ADMIN_INVALID_ACCOUNT, "用户帐号或密码不正确");
    } catch (LockedAccountException lae) {
    logHelper.logAuthFail("登录", "用户帐号已锁定不可用");
    return ResponseUtil.fail(ADMIN_INVALID_ACCOUNT, "用户帐号已锁定不可用");

    } catch (AuthenticationException ae) {
    logHelper.logAuthFail("登录", "认证失败");
    return ResponseUtil.fail(ADMIN_INVALID_ACCOUNT, "认证失败");
    }
        //通过shrio获取当前用户信息。
    currentUser = SecurityUtils.getSubject();
        //刷新用户表信息。
    LitemallAdmin admin = (LitemallAdmin) currentUser.getPrincipal();
    admin.setLastLoginIp(IpUtil.getIpAddr(request));
    admin.setLastLoginTime(LocalDateTime.now());
    adminService.updateById(admin);
        //写入数据库日志
    logHelper.logAuthSucceed("登录");

    // 将用户信息返回到前端后台。
    Map<String, Object> adminInfo = new HashMap<String, Object>();
    adminInfo.put("nickName", admin.getUsername());
    adminInfo.put("avatar", admin.getAvatar());
        //最重要的一点,将当前登录后的Session写回到前端后台,当前端再发起请求时,
        //会调用src/main/java/org/linlinjava/litemall/admin/shiro/AdminWebSessionManager.java
        //中的getSessionId获取前端通过http头发送过来的session,交由后台验证当前的登录状态和权限。
    Map<Object, Object> result = new HashMap<Object, Object>();
    result.put("token", currentUser.getSession().getId());
    result.put("adminInfo", adminInfo);
    return ResponseUtil.ok(result);
    }

    litemall前后端分离的总结。
    这篇文章创建的比较早,但其实是在完成4.04后才补充完毕的。大体上也了解了整体上的思路。

    在传统前后端不分离的项目中。session与http申请都在一个后台中,所以可以统一处理这些关系。

    但分离后,会有跨域的问题,即浏览器在加载一个服务器的资源后,访问另一个服务器的资源。

    我一直以为这个问题。。。没什么好解释的,但仔细想来,也没这么简单。

    首先说下vue后台的理解。vue后台,只是提供给浏览器相应的html和js代码。浏览器的运行状态如何,

    vue后台是一点也不知道,一点也不管的。我曾经有个问题,就是vuex保存java后台的session,会不会

    不同用户导致混乱,想明白这个问题后答案就很明确了。vuex本身就是保存在浏览器的,每个浏览器

    都有一个实例。肯定不会发生混乱。

    那么第二个问题来了,既然vue相关代码全都是运行在浏览器的,所有http请求,包括登录都是全部发往java后台的。

    session为什么会有失效的问题呢?

    我搜了好久,但更多的是讲处理办法,而非本质原因。

    个人感觉这篇文章讲的很好。

    首先我们先了解http是无状态协议。压根就不知道一个申请过来,这个申请的发起者

    有没有登录过。所以有了cookie与session。

    cookie是保存在浏览器端的。session是保存在服务器端的。

    当一个浏览器发起连接,服务器创建一个session。该浏览器登录成功,服务器在session里设置一个属性标识该用户登录。

    之后,将sessionID返回给客户,保存在浏览器中。当该浏览器再次发起请求,并且带着这个sessionID,服务器根据该ID检测,

    该用户是否已经进行了登录,再进行后续操作。

    那么回到session失效的问题。

    我们登录页的后台地址实际上是vue后台,而登录的地址却是向java后台发申请。

    这时候浏览器的同源策略就会阻止cookie的一些操作。因为这会带来风险,这篇文章有简单描述。

    但是,我现在并不详细地了解这边是怎么具体操作的,是阻止java后台向当前vue后台的cookie里写内容。

    或者阻止在向java后台发起http请求时,读内容。我想应该是前者。

    但这边传统的session策略肯定是失效的。

    回到litemall权限验证上来。当我们想java后台发出登录请求,java后台返回session后,我们

    直接将session写入到了vuex中。当再向java后台发出http请求,从vuex中读取该session代替浏览器默认的session。

    这也是为什么java后台要重写src/main/java/org/linlinjava/litemall/admin/shiro/AdminWebSessionManager.java。

    就是在读取session是,不读取默认的sessionID,而是使用http请求头中的X-Litemall-Admin-Token代替了session。

    到这里登录验证应该差不多写完了。

    我在读登录验证以前,一直以为权限验证是登录时直接把权限返回的,现在看来并不是。接下来阅读权限验证的源码。

  • 相关阅读:
    B.Little Sub and Triples
    A.Little Sub and Applese
    1003 超级无敌简单题[暴力打表]
    1002 人类史上最大最好的希望事件[前缀和]
    1001 hzy 和zsl 的生存挑战
    Computer Arrangement [经典贪心]
    Linux指令
    LInux
    Servlet
    El表达式与JSTL表达式
  • 原文地址:https://www.cnblogs.com/xiaoBay/p/14055535.html
Copyright © 2011-2022 走看看