Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >SpringBoot集成SpringSecurity - 自动登录(二)

SpringBoot集成SpringSecurity - 自动登录(二)

作者头像
用户1212940
发布于 2022-04-13 09:03:37
发布于 2022-04-13 09:03:37
59100
代码可运行
举报
文章被收录于专栏:LambdaLambda
运行总次数:0
代码可运行

源码地址https://github.com/springsecuritydemo/microservice-auth-center02

在上一章入门案例 中,我们实现了入门程序,本篇我们在上一章的基础上完成自动登录功能。

一、修改登录页面:login.html

在登录页面中添加自动登录复选框,自动登录字段名必须为:remember-me

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登陆</title>
</head>
<body>
<h1>登陆</h1>
<form method="post" action="/login">
    <div>
        用户名:<input type="text" name="username">
    </div>
    <div>
        密 码:<input type="password" name="password">
    </div>
    <div>
        <label><input type="checkbox" name="remember-me"/>自动登录</label>
    </div>
    <div>
        <button type="submit">立即登陆</button>
    </div>
</form>
</body>
</html>

二、自动登录两种实现方式

2.1 Cookie 存储

这种方式十分简单,只需要在 WebSecurityConfig 中的 configure() 方法中添加一个 rememberMe() 即可,代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private CustomUserDetailsService userDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                // 如果有允许匿名的url,填在下面
//                .antMatchers().permitAll()
                .anyRequest().authenticated()
                .and()
                // 设置登陆页
                .formLogin().loginPage("/login")
                // 设置登陆成功页
                .defaultSuccessUrl("/").permitAll()
                // 自定义登陆用户名和密码参数,默认为username和password
//                .usernameParameter("username")
//                .passwordParameter("password")
                .and()
                .logout().permitAll()
                // 自动登录
                .and().rememberMe();

        // 关闭CSRF跨域
        http.csrf().disable();
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        // 设置拦截忽略文件夹,可以对静态资源放行
        web.ignoring().antMatchers("/css/**", "/js/**");
    }
}

当我们登录时勾选【自动登录】时,会自动在 Cookie 中保存一个名为 remember-me 的cookie,默认有效期为2周,其值是一个加密字符串:

当再次访问系统首页时,浏览器会携带这个 cookie 进行访问,SpringSecurity校验Cookie的有效性,完成自动登录。

2.2 数据库存储

使用 Cookie 存储虽然方便,但是大家都知道 Cookie 毕竟是保存在客户端的,而且 Cookie 的值还与用户名、密码这些敏感信息有关,虽然加密了,但是将这些敏感信息存在客户端,毕竟不太保险。(万一遇到黑客给黑了就尴尬了┭┮﹏┭┮)

**SpringSecurity 还提供了另一种相对安全的实现机制: **

  • 在客户端的 Cookie中,仅保存一个无意义的加密串(与用户名和密码等敏感信息无关),然后在数据库中保存该加密串 - 用户信息的对应关系,自动登录时,用 Cookie 中的加密串,到数据库验证,如果通过,自动登录才算成功。
2.2.1 基本原理

当浏览器发起表单登录请求时,当通过 UsernamePasswordAuthenticationFilter 认证成功后,会经过 RememberMeService, 在其中有个 TokenRepository , 它会生成一个 token, 首先将 token 写入到浏览器的 Cookie中,然后将 token、认证成功的用户名写入到数据库中。

当浏览器下次请求时,会经过 RememberMeAuthenticationFilter,它会读取 Cookie 中的 token,交给 RememberMeService ,获取用户信息,并将用户信息放入到 SpringSecurity 中,实现自动登录。

RememberMeAuthenticationFilter在整个过滤器链中是比较靠后的位置,也就是说在传统的登录方式都无法登录情况下才会使用自动登录。

2.2.2 代码实现

在 WebSecurityConfig 中注入 dataSource ,创建一个 PersistentTokenRepository 的Bean对象:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    @Autowired
    private DataSource dataSource;

    @Bean
    public PersistentTokenRepository persistentTokenRepository() {
        JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
        tokenRepository.setDataSource(dataSource);
        // 如果token表不存在,使用下面可以自动初始化表结构,如果已经存在,请注释掉,否则会报错
        // tokenRepository.setCreateTableOnStartup(true);
        return tokenRepository;
    }

在 config() 中配置自动登录:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                // 如果有允许匿名的url,填在下面
//                .antMatchers().permitAll()
                .anyRequest().authenticated()
                .and()
                // 设置登陆页
                .formLogin().loginPage("/login")
                // 设置登陆成功页
                .defaultSuccessUrl("/").permitAll()
                // 自定义登陆用户名和密码参数,默认为username和password
//                .usernameParameter("username")
//                .passwordParameter("password")
                .and()
                .logout().permitAll()
                // 自动登录
                .and().rememberMe()
                .tokenRepository(persistentTokenRepository())
                // 有效时间,单位:s
                .tokenValiditySeconds(60)
                .userDetailsService(userDetailsService);

        // 关闭CSRF跨域
        http.csrf().disable();
    }

初次启动,如果配置自动生成token表结构,会默认在数据库中生成:

表结构:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CREATE TABLE `persistent_logins` (
  `username` varchar(64) NOT NULL,
  `series` varchar(64) NOT NULL,
  `token` varchar(64) NOT NULL,
  `last_used` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`series`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

生产环境推荐,手动创建表,免得再修改代码配置

三、运行测试

勾选自动登录后,Cookie 和数据库中均存储了 token 信息:

关闭浏览器,在cookie没有过期之前,直接访问 http://localhost:9000/ 系统首页无需登录可直接访问。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019/07/23 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【Git】Git 完全指南:从入门到精通
Git 是现代软件开发中最重要的版本控制工具之一,它帮助开发者高效地管理项目,支持分布式协作和版本控制。无论是个人项目还是团队开发,Git 都能提供强大的功能来跟踪、管理代码变更,并保障项目的稳定性与可持续发展。本篇文章从基础命令讲起,逐步深入,帮助你全面了解并掌握 Git,最终达到精通。
LuckiBit
2024/12/11
4.6K0
【Git】Git 完全指南:从入门到精通
Git Cheat 2
整理一下经常忘记的Git命令 (版本v2) http://www.ruanyifeng.com/blog/2015/12/git-cheat-sheet.html?utm_source=tool.lu
happy123.me
2018/06/04
5510
不会吧?你这些Git命令都不会~
1、设置与帮助 1. git help <command> # 显示指定命令的help 2. git config --global user.name "your name" 3. git config --global user.email "your email" 2、修改与提交 1. git status # 查看工作区状态 2. git add <file> # 将指定文件修改提交到本地暂存区 3.
chengcheng222e
2021/11/04
4460
Git常见命令与使用,从0到1学会使用Git
才疏学浅的木子
2023/10/17
1700
Git常见命令与使用,从0到1学会使用Git
Git 帮助手册
国外网友制作了一张 Git Cheat Sheet,总结很精炼,各位不妨收藏一下。
硬件开源小站
2023/04/07
4.4K1
Git 帮助手册
git 命令大全
阮一峰 git 学习 :https://www.ruanyifeng.com/blog/2015/12/git-cheat-sheet.html
xyzzz
2020/12/12
6220
git 命令大全
Git-基本命令大全
Workspace:工作区 Index / Stage:暂存区 Repository:仓库区(或本地仓库) Remote:远程仓库
腾讯工蜂
2018/11/07
1.4K0
开发中必须要掌握的 Git 技巧
本文是参考廖雪峰老师的Git资料再加上我自己对Git的理解,记录我的Git学习历程,作下此文是为以后学习,工作,开发中如果遇到问题可以回过头来参考参考。因为水平有限,难免会有出错的地方,欢迎指正。
Java团长
2019/08/15
6070
Git 常用命令清单笔记
这里是我的笔记,记录一些git常用和一些记不住的命令,这个笔记原本是基于 颜海镜的文章增加的,后面慢慢增加了许多内容,可以看出的的学习轨迹。分享出来方便自己查看,也许能帮助到你。
小弟调调
2018/09/11
7990
Git 常见命令及其命令组合
GeekLiHua
2024/08/22
1430
三年 Git 使用心得 & 常见问题整理
「使用场景:」 当你接到一个修复紧急 bug 的任务时候,一般都是先创建一个新的 bug 分支来修复它,然后合并,最后删除。但是,如果当前你正在开发功能中,短时间还无法完成,无法直接提交到仓库,这时候可以先把当前工作区的内容 git stash 一下,然后去修复 bug,修复后,再 git stash pop,恢复之前的工作内容。
Nealyang
2020/06/19
2.9K0
三年 Git 使用心得 & 常见问题整理
看了这篇文章,你应该可以应付工作中90%的git命令
安装完git 需设置账号和邮箱,用于标示用户身份,类似于svn的账号,但是git不存在服务器,所以无需密码验证身份。 保存位置C:\Users\yourname\\.gitconfig。
兜兜转转
2023/03/08
4560
Git常用操作指南
因为工作需求,最近又重新温习了一下Git操作,遂总结了一篇Git常用操作指南,方便日后学习查阅,本博客精简提炼了在开发过程中Git经常用到的核心命令,主要参考了《廖雪峰老师的Git教程》,希望对大家学习使用Git能带来帮助。
10JQKA
2019/07/22
8110
Git常用操作指南
Git命令语法汇总
本文是在学习廖雪峰Git教程后对常用Git命令的使用总结,仅供在使用Git时方便查找。 一、Git简介 Git是当前最为流行的分布式版本控制系统,尤其是2008年,GitHub网站上线了,它为开源
梧雨北辰
2018/04/24
9010
Git命令语法汇总
git学习总结03 — 分支管理
merge 分支合并有 fast-forward 和 no-fast-forward 两种模式。下图 dev 合入 master,默认触发快进模式(fast-forward),因为只需要修改指针即可实现合并;而普通模式(no-fast-forward)需要生成一个新的commit,因此即使 dev 分支删除,也能从 master 分支历史上看出分支合并信息。
CS逍遥剑仙
2020/05/30
1.5K0
Git关键命令总结
git reset命令既可以回退版本,也可以把暂存区的修改回退到工作区。当我们用HEAD时,表示最新的版本。(个人体会:其实是把暂存区的版本还原到最近一次提交后的版本库的版本,相当于清空了readme.txt未提交的修改,暂存区现在不存在这个待提交修改,但工作区的文件不会受影响,可以再次add将该修改放到暂存区,也可以使用git checkout -- readme.txt将工作区的文件撤回到最近版本的状态
梦飞
2022/06/23
5760
Git关键命令总结
相关推荐
【Git】Git 完全指南:从入门到精通
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验