Spring boot后台搭建二集成Shiro添加Remember Me


上一片文章實現了用戶驗證  查看

當用戶成功登錄后,關閉瀏覽器,重新打開瀏覽器訪問http://localhost:8080,頁面會跳轉到登錄頁,因為瀏覽器的關閉后之前的登錄已失效

Shiro提供了Remember Me的功能,用戶的登錄狀態不會因為瀏覽器的關閉而失效,直到Cookie過期

1.修改ShiroConfig

(1)添加

/**
     * cookie對象
     * @return
     */
    public SimpleCookie rememberMeCookie() {
        // 設置cookie名稱,對應login.html頁面的<input type="checkbox" name="rememberMe"/>
        SimpleCookie cookie = new SimpleCookie("rememberMe");
        // 設置cookie的過期時間,單位為秒,這里為一天
        cookie.setMaxAge(86400);
        return cookie;
    }

    /**
     * cookie管理對象
     * @return
     */
    public CookieRememberMeManager rememberMeManager() {
        CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
        cookieRememberMeManager.setCookie(rememberMeCookie());
        // rememberMe cookie加密的密鑰
        cookieRememberMeManager.setCipherKey(Base64.decode("4AvVhmFLUs0KTA3Kprsdag=="));
        return cookieRememberMeManager;
    }

(2)將cookie管理對象設置到SecurityManager

  修改securityManager()為

@Bean
    public SecurityManager securityManager() {
        DefaultWebSecurityManager securityManager =  new DefaultWebSecurityManager();
        securityManager.setRealm(myShiroRealm());
        securityManager.setRememberMeManager(rememberMeManager());//新加
        return securityManager;
    }

(3)改權限配置

  將ShiroFilterFactoryBean的

filterChainDefinitionMap.put("/**", "authc")

  修改為

filterChainDefinitionMap.put("/**", "user");

說明:

  user指的是用戶認證通過或者配置了Remember Me記住用戶登錄狀態后可訪問

2.修改login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" th:href="@{/css/login.css}" type="text/css">
    <link rel="stylesheet" th:href="@{css/iCheck/minimal/blue.css}" type="text/css">
    <link rel="stylesheet" th:href="@{css/app.css}" type="text/css">
    <script th:src="@{/js/jquery.min.js}"></script>
</head>
<body>
<div class="login-page">
    <!-- Form-->
    <div class="form">
        <div class="form-toggle"></div>
        <div class="form-panel one">
            <div class="form-header">
                <h1>賬戶登錄</h1>
            </div>
            <div class="form-content">
                <div class="form-group">
                    <label>用戶名</label>
                    <input type="text" name="account" />
                </div>
                <div class="form-group">
                    <label>密碼</label>
                    <input type="password" name="password" />
                </div>
                <div class="form-group" style="margin: 0px;">
                    <p>
                        <input type="checkbox" name="rememberMe" />&nbsp;&nbsp;記住我</p>
                </div>
                <div class="form-group">
                    <button onclick="login()" id="loginButton">登錄</button>
                </div>
            </div>
        </div>
    </div>

</div>
</body>
<script th:inline="javascript">
    var ctx = [[@{/}]];
        function login() {
            var account = $("input[name='account']").val();
            var password = $("input[name='password']").val();
            var rememberMe = $("input[name='rememberMe']").is(':checked');
            $.ajax({
                type: "post",
                url: ctx + "login",
                data: {"account": account,"password": password,"rememberMe": rememberMe},
                dataType: "json",
                success: function (r) {
                    if (r.code == 0) {
                        location.href = ctx + 'index';
                    } else {
                        alert(r.msg);
                    }
                }
            });
        }
</script>
</html>
View Code

3.修改LoginController

@PostMapping("/login")
    @ResponseBody
    public ResponseBo login(String account, String password, Boolean rememberMe) {
        System.out.println(rememberMe);
        // 密碼MD5加密
        password = MD5Utils.encrypt(account, password);
        System.out.println(password);
        UsernamePasswordToken token = new UsernamePasswordToken(account, password);
        rememberMe = rememberMe == null ? false : rememberMe;   //null=>false
        token.setRememberMe(rememberMe);
        //UsernamePasswordToken token = new UsernamePasswordToken(username, password,rememberMe);
        // 獲取Subject對象
        Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(token);
            if (rememberMe)  System.out.println("rememberMe--------");
            return ResponseBo.ok();
        } catch (UnknownAccountException e) {
            return ResponseBo.error(e.getMessage());
        } catch (IncorrectCredentialsException e) {
            return ResponseBo.error(e.getMessage());
        } catch (LockedAccountException e) {
            return ResponseBo.error(e.getMessage());
        } catch (AuthenticationException e) {
            return ResponseBo.error("認證失敗!");
        }
    }
View Code

rememberMe選中的時候,Shiro就會幫忙記住用戶的登錄狀態

 說明:

  如果遇到下面錯誤

2019-06-24 15:37:49.620 WARN 12952 --- [nio-8088-exec-2] o.a.shiro.mgt.DefaultSecurityManager : Delegate RememberMeManager instance of type [org.apache.shiro.web.mgt.CookieRememberMeManager] threw an exception during onSuccessfulLogin. RememberMe services will not be performed for account [com.sfn.bms.system.model.User@86fc436].

org.apache.shiro.io.SerializationException: Unable to serialize object [com.sfn.bms.system.model.User@86fc436]. In order for the DefaultSerializer to serialize this object, the [org.apache.shiro.subject.SimplePrincipalCollection] class must implement java.io.Serializable.

  解決方法查看


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM