一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - springboot整合shiro實現記住我功能

springboot整合shiro實現記住我功能

2022-02-28 13:06桐花思雨 Java教程

這篇文章主要介紹了springboot整合shiro實現記住我功能,配置類 ShiroConfig,通過實例代碼給大家介紹的非常詳細,需要的朋友可以參考下

前言

上一篇 文章我們完成了在 thymeleaf 模板引擎中使用 shiro 標簽,也就是根據不同的用戶身份信息,前端頁面來顯示不同的頁面內容。本篇文章我們來完成在登錄頁面的記住我的功能

springboot 整合 shiro 之實現記住我

項目依然使用 springboot整合shiro 這個項目,稍稍改動即可完成記住我的功能

配置類 ShiroConfig

完整的代碼如下

@Configuration
public class ShiroConfig {

    /**
     * 安全管理器
     *
     * @param userRealm userRealm
     * @return defaultWebSecurityManager
     */
    @Bean
    public DefaultWebSecurityManager getDefaultWebSecurityManager(UserRealm userRealm) {
        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
        defaultWebSecurityManager.setRealm(userRealm);
        // 實現記住我,所需要的配置
        defaultWebSecurityManager.setRememberMeManager(cookieRememberMeManager());
        return defaultWebSecurityManager;
    }

    /**
     * thymeleaf模板引擎中使用shiro標簽時,要用到
     *
     * @return
     */
    @Bean
    public ShiroDialect getShiroDialect() {
        return new ShiroDialect();
    }

    @Bean
    public ShiroFilterFactoryBean shiroFilter(DefaultWebSecurityManager defaultWebSecurityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
        // 設置登錄頁面url
        shiroFilterFactoryBean.setLoginUrl("/user/login");
        shiroFilterFactoryBean.setSuccessUrl("/user/index");
        shiroFilterFactoryBean.setUnauthorizedUrl("/user/unauthorized");

        // 注意此處使用的是LinkedHashMap是有順序的,shiro會按從上到下的順序匹配驗證,匹配了就不再繼續驗證
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();

        filterChainDefinitionMap.put("/layer/**", "anon");// 靜態資源放行
        filterChainDefinitionMap.put("/img/**", "anon");
        filterChainDefinitionMap.put("/jquery/**", "anon");
        // add.html頁面放行
        filterChainDefinitionMap.put("/user/add", "authc");
        // update.html必須認證
        filterChainDefinitionMap.put("/user/update", "authc");
        // index.html必須認證
        filterChainDefinitionMap.put("/user/index", "user");
        // 設置授權,只有user:add權限的才能請求/user/add這個url
        filterChainDefinitionMap.put("/user/add", "perms[user:add]");
        filterChainDefinitionMap.put("/user/update", "perms[user:update]");

        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }

	// 實現記住我,所需要的配置
    @Bean
    public SimpleCookie simpleCookie() {
        // 這個參數是cookie的名稱,對應前端的checkbox的name = rememberMe
        SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
        simpleCookie.setHttpOnly(true);
        // 記住我cookie生效時間1小時,單位秒
        simpleCookie.setMaxAge(60 * 60);
        return simpleCookie;
    }

	// 實現記住我,所需要的配置
    @Bean
    public CookieRememberMeManager cookieRememberMeManager() {
        CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
        cookieRememberMeManager.setCookie(simpleCookie());
        // rememberMe cookie加密的密鑰 建議每個項目都不一樣 默認AES算法 密鑰長度(128 256 512 位)
        cookieRememberMeManager.setCipherKey(Base64.decode("4AvVhmFLUs0KTA3Kprsdag=="));
        return cookieRememberMeManager;
    }
}

login.html 登錄頁面

此時要拿到復選框 checkbox 是否被用戶選中的狀態值,選中為 true,未選中為 false,將這個狀態值發生至后端登錄接口

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>登錄</title>
    <link rel="shortcut icon" type="image/x-icon" th:href="@{/img/favicon.ico}"/>
</head>
<body>
<form action="" method="post">
    <p>
        賬號:
        <label><input type="text" class="username" name="username"></label>
    </p>
    <p>
        密碼:
        <label><input type="text" class="password" name="password"></label>
    </p>
    <p>
        <label><input id="checkbox1" type="checkbox" name="rememberMe"></label>記住我
    </p>
    <p><button type="button" class="loginBtn">登錄</button></p>
</form>
</body>
<script type="text/javascript" th:src="@{/jquery/jquery-3.3.1.min.js}"></script>
<script type="text/javascript" th:src="@{/layer/layer.js}"></script><!--layui的彈出層-->
<script type="text/javascript">
    $(document).ready(function () {
        $(".loginBtn").on("click", function () { // 登錄按鈕
            const username = $(".username").val();
            const password = $(".password").val();
            const rememberMe = $("input[type="checkbox"]").is(":checked");
            $.ajax({// 用戶登錄
                type: "post",
                url: "/user/doLogin",
                dataType: "json",
                data: ({
                    "username": username,
                    "password": password,
                    "rememberMe": rememberMe
                }),
                success: function (resp) {
                    console.log(resp);
                    if (resp.code !== 200) {
                        layer.msg(resp.message, function () {// layui的彈窗
                        });
                    } else if (resp.code === 200) {
                        window.location.href = "http://127.0.0.1:8080"+ resp.action;
                    }
                },
                error: function () {// 此處添加錯誤處理
                    layer.open({
                        title: "提示信息",
                        content: "后臺訪問錯誤,請聯系管理員",
                        skin: "layui-layer-molv",
                        icon: 0
                    });
                }
            });
        });
    });
</script>
</html>

controller

@Controller
@RequestMapping(path = "/user")
@Slf4j
public class UserController {

    @GetMapping(path = "/login")
    public String login() {
        return "login";
    }

    @GetMapping(path = "/index")
    public String index() {
        return "index";
    }

    @GetMapping(path = "/add")
    public String add() {
        return "add";
    }

    @GetMapping(path = "/update")
    public String update() {
        return "update";
    }

    @GetMapping(path = "/unauthorized")
    public String unauthorized() {
        return "unauthorized";
    }

    /**
     * 用戶登錄
     *
     * @param userVO
     * @param bindingResult
     * @return
     */
    @PostMapping(path = "/doLogin")
    @ResponseBody
    public ResultMap doLogin(@NotNull @Valid UserVO userVO, @NotNull BindingResult bindingResult) {
        // ------參數校驗------
        if (bindingResult.hasErrors()) {
            String message = Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage();
            log.info("校驗的message信息為:" + message);
            return new ResultMap().fail().message(message);
        }
        // 將用戶名,密碼交給shiro
        UsernamePasswordToken token = new UsernamePasswordToken(userVO.getUsername(), userVO.getPassword(), userVO.getRememberMe());
        String msg;
        try {
            // shiro幫我們匹配密碼什么的,我們只需要把東西傳給它,它會根據我們在UserRealm里認證方法設置的來驗證
            Subject subject = SecurityUtils.getSubject();
            subject.login(token);
            return new ResultMap().success().action("/user/index");
        } catch (AuthenticationException e) {
            if (e instanceof IncorrectCredentialsException) {
                msg = "密碼錯誤";
            } else if (e instanceof LockedAccountException) {
                msg = "用戶被禁用";
            } else if (e instanceof UnknownAccountException) {
                msg = "用戶不存在";
            } else {
                msg = "用戶認證失敗";
            }
        }
        return new ResultMap().error().message(msg);
    }

    /**
     * 用戶退出登錄
     * 添加記住我功能了,退出登錄時,除了要當前的subject退出之外,還要刪除用戶瀏覽器上的Cookie信息
     *
     * @return
     */
    @GetMapping(path = "/logout")
    public String logout(HttpServletResponse response) {
        Subject subject = SecurityUtils.getSubject();
        if (subject.isAuthenticated()) {
            subject.logout();
            Cookie cookie = new Cookie("rememberMe", null);
            cookie.setMaxAge(0);
            response.addCookie(cookie);
        }
        return "login";
    }
}

UserVO

public class UserVO implements Serializable {

    @NotBlank(message = "賬號不能為空")
    private String username;

    @NotEmpty(message = "密碼不能為空")
    private String password;

    private Boolean rememberMe;

	// 省略set/get方法
}

測試

我們以賬號 jack 為例進行登錄,如下

springboot整合shiro實現記住我功能

進入首頁頁面如下,再次查看 Cookies 數據

springboot整合shiro實現記住我功能

我們這時關閉這個首頁頁面,在瀏覽器地址欄輸入 http://127.0.0.1:8080/user/index 再次進入首頁頁面,會發現如上圖一樣,可以順利訪問,說明我們的記住我功能已經實現。這時,可以再次在瀏覽器地址欄輸入 http://127.0.0.1:8080/user/add,進入 add.html 頁面,如下

springboot整合shiro實現記住我功能

Cookies 的有效期內,當你關閉瀏覽器之后,再次進入 add.html 頁面時,無需登錄直接就可以訪問了,說明記住我功能已經實現了。在瀏覽器地址欄輸入 http://127.0.0.1:8080/user/update,進入 update.html 頁面,如下

springboot整合shiro實現記住我功能

說明賬號 jack 沒有權限訪問 update.html 頁面,可以看控制臺 sql 日志

springboot整合shiro實現記住我功能

源碼:springboot-shiro

到此這篇關于springboot整合shiro之實現記住我的文章就介紹到這了,更多相關springboot整合shiro之實現記住我內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://blog.csdn.net/weixin_38192427/article/details/120928810

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 99国产精品久久久久久久... | 性做久久久久久久久浪潮 | kisssis无减删全集在线观看 | 国产成人精品曰本亚洲77美色 | 热99re久久精品精品免费 | 免费港剧在线观看港剧 | 无套大战白嫩乌克兰美女 | 日本色频 | 特黄特色大片免费视频播放 | 午夜日本大胆裸艺术 | 动漫精品午夜在线播放 | 91爱爱网站 | 国产99re在线观看69热 | 亚洲国产精品二区久久 | 深夜成人 | 干美女在线视频 | 国产精品合集一区二区 | 免费特黄一级欧美大片在线看 | 欧美成人禁片在线观看俄罗斯 | 香蕉97超级碰碰碰免费公 | 狠狠色综合久久婷婷色天使 | 亚洲看片lutube在线入口 | av91在线| 精精国产xxxx视频在线播放器 | 男女激情网 | 国产首页精品 | 免费理伦片手机在线播放 | 国产外围 | 91tm视频 | 高清不卡一区二区 | 四虎永久免费地址 | 国产主播福利在线观看 | 国产主播精品在线 | 91精品综合国产在线观看 | 欧美人与物videos另类3d | 精品国产美女福利在线 | 俄罗斯烧性春三级k8播放 | 国产精品原创视频 | 亚洲人成绝费网站色ww | 91精品国产高清久久久久久 | 色综合伊人色综合网站中国 |