编程

当前位置:永利皇宫463登录 > 编程 > 简单的登录认证,基于登录认证记住我实例

简单的登录认证,基于登录认证记住我实例

来源:http://www.makebuLuo.com 作者:永利皇宫463登录 时间:2019-10-11 09:51
@Configurationpublic class TemplateConfig implements WebMvcConfigurer { @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController.setViewName; registry.addViewController.setViewName; registry.addViewController.setViewName; }}

首先,导入jquery.cookie.js

从上边index.html能够看来包蕴了一个"/hello"连接点击跳转到hello.html页面包车型大巴简要流程

本篇小说基于Spring Security 入门教程 - 轻松的报到认证 基础上改变的记忆犹新小编教程。

$(function(){
   //初始化页面时验证是否记住了密码
    if ($.cookie("autologin") == "true") {
        $("#autologin").attr("checked", true);
        $("#account").val($.cookie("account"));
        $("#pwd").val($.cookie("pwd"));
    }
});

//保存用户信息
function saveUserInfo() {
  var  xuanzhong = document.getElementById("autologin").checked;
  if (xuanzhong) {
    var account = $("#account").val();
    var pwd = $("#pwd").val();
    $.cookie("autologin", "true", { expires: 7 }); // 存储一个带7天期限的 cookie
    $.cookie("account", account, { expires: 7 }); // 存储一个带7天期限的 cookie
  $.cookie("pwd", pwd, { expires: 7 }); // 存储一个带7天期限的 cookie
  }
  else {
    $.cookie("autologin", "false", { expires: -1 });
    $.cookie("account", '', { expires: -1 });
    $.cookie("pwd", '', { expires: -1 });
  }
}

在项目标src/main/resources下进展陈设

5.2 登陆成功后会挑衅到index.html页面,通过debug开掘,spring security已经为大家分配了刚刚命名的cookie。

图片 1

正文介绍下jquery 记住登入信息的办法,引进jquery.cookie.js文件,达成记住登入消息,有亟待的情沙参谋下。

路径:src/main/resources/templates/hello.html

package com.bootcap.session.security.configuration;/** * 2018-12-10 11:03 */@Configuration@EnableWebSecuritypublic class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override public void configure(WebSecurity web) throws Exception { web.ignoring() .antMatchers("/js/**","/img/**"); } // 重点修改的方法 @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .anyRequest().authenticated .formLogin() .loginPage .permitAll().defaultSuccessUrl .and() .logout() .invalidateHttpSession .clearAuthentication .logoutRequestMatcher(new AntPathRequestMatcher("/logout")) .logoutSuccessUrl("/login?logout") .permitAll .rememberMe() .key("unique-and-secret") .rememberMeCookieName("rememberMeCookieName") // 设置cookie名称 .tokenValiditySeconds(24 * 60 * 60); // 设置令牌有效期,若不自定义:默认为2周 } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() // 在内存中进行身份验证 .passwordEncoder(new BCryptPasswordEncoder .withUser .password(new BCryptPasswordEncoder().encode) .roles; }}

jquery.cookie.js

何以行使

: 由于本人本中国人民银行使的是idea举行支付,由此对eclipse的引进是不是须要火速键并不是很明亮,提供了连带链接

IDEA使用:

  • 修改了java类的地点,使用Ctrl+Shift+F9进展热更新
  • 静态页面/模板页面,使用Ctrl+F9拓宽热更新
  • 飞速键使用后不见效?前往File-Settings-Compiler-Build Project automatically选项最早idea自动编写翻译

eclipse使用:

  • 一向引进
  • 不生效?Eclipse热部署
方法 说明
openidLogin() 基于OpenId验证
headers() 将安全头添加到响应
cors() 跨域配置
sessionManagement() session会话管理
portMapper() 配置一个PortMapper(HttpSecurity#(getSharedObject,供SecurityConfigurer对象使用 PortMapper 从 HTTP 重定向到 HTTPS 或者从 HTTPS 重定向到 HTTP。默认情况下,Spring Security使用一个PortMapperImpl映射 HTTP 端口8080到 HTTPS 端口8443,HTTP 端口80到 HTTPS 端口443
jee() 配置容器预认证,默认为Servlet容器进行管理
x509() 配置x509认证
rememberMe() 配置“记住我”的验证
authorizeRequests() 允许HttpServletRequest限制访问
requestCache() 允许配置请求缓存
exceptionHandling() 允许配置错误处理
logout() 退出登录。访问URL”/ logout”,使HTTP Session无效来清除用户,清除已配置的任何#rememberMe()身份验证,清除SecurityContextHolder,然后重定向到”/login?logout”
anonymous() 允许配置匿名用户访问。默认情况下,匿名用户将使用org.springframework.security.authentication.AnonymousAuthenticationToken表示,并包含角色 “ROLE_ANONYMOUS”
formLogin() 指定用于表单身份验证。
oauth2Login() 用于OAuth 2.0 或OpenID的身份验证
requiresChannel() 配置通道安全。
httpBasic() 配置Http Basic验证
addFilterAt() 在指定的Filter类位置添加过滤器

下一篇:Spring Security 入门教程 - 基于数据库消息进行求证

5.3 为了评释是记住本人报到,我们把JSESSIONID删除,并刷新页面,会开掘又刚删除的JSESSIONID又发生了。并且Value值已经更改。

图片 2

上一篇:Spring Security 入门教程- 基于数据库音信举办表达下一篇:Spring Security 入门教程- 权限动态修改

/**
 * Cookie plugin
 *
 * Copyright (c) 2006 Klaus Hartl (stilbuero.de)
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 *
 */

/**
 * Create a cookie with the given name and value and other optional parameters.
 *
 * @example $.cookie('the_cookie', 'the_value');
 * @desc Set the value of a cookie.
 * @example $.cookie('the_cookie', 'the_value', {expires: 7, path: '/', domain: 'jquery.com', secure: true});
 * @desc Create a cookie with all available options.
 * @example $.cookie('the_cookie', 'the_value');
 * @desc Create a session cookie.
 * @example $.cookie('the_cookie', null);
 * @desc Delete a cookie by passing null as value.
 *
 * @param String name The name of the cookie.
 * @param String value The value of the cookie.
 * @param Object options An object literal containing key/value pairs to provide optional cookie attributes.
 * @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object.
 *                             If a negative value is specified (e.g. a date in the past), the cookie will be deleted.
 *                             If set to null or omitted, the cookie will be a session cookie and will not be retained
 *                             when the the browser exits.
 * @option String path The value of the path atribute of the cookie (default: path of page that created the cookie).
 * @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie).
 * @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will
 *                        require a secure protocol (like HTTPS).
 * @type undefined
 *
 * @name $.cookie
 * @cat Plugins/Cookie
 * @author Klaus Hartl/klaus.hartl@stilbuero.de
 */

/**
 * Get the value of a cookie with the given name.
 *
 * @example $.cookie('the_cookie');
 * @desc Get the value of a cookie.
 *
 * @param String name The name of the cookie.
 * @return The value of the cookie.
 * @type String
 *
 * @name $.cookie
 * @cat Plugins/Cookie
 * @author Klaus Hartl/klaus.hartl@stilbuero.de
 */
jQuery.cookie = function(name, value, options) {
    if (typeof value != 'undefined') { // name and value given, set cookie
        options = options || {};
        if (value === null) {
            value = '';
            options.expires = -1;
        }
        var expires = '';
        if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
            var date;
            if (typeof options.expires == 'number') {
                date = new Date();
                date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
            } else {
                date = options.expires;
            }
            expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
        }
        var path = options.path ? '; path=' + options.path : '';
        var domain = options.domain ? '; domain=' + options.domain : '';
        var secure = options.secure ? '; secure' : '';
        document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
    } else { // only name given, get cookie
        var cookieValue = null;
        if (document.cookie && document.cookie != '') {
            var cookies = document.cookie.split(';');
            for (var i = 0; i < cookies.length; i++) {
                var cookie = jQuery.trim(cookies[i]);
                // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length + 1) == (name + '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        return cookieValue;
    }
};
8.3 大家输入错误的新闻会唤起客户名或密码不正确,同有的时候间地址栏的地点也形成了"/login?error"

图片 3image

4.2 修改index.html
<!DOCTYPE html><html xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.w3.org/1999/xhtml"><head> <meta charset="utf-8"/> <meta http-equiv="X-UA-Compatible" content="IE=edge"/> <meta name="viewport" content="width=device-width, initial-scale=1"/> <title>Spring Security 登录认证记住我实例</title></head><body><div > <h1>Spring Security 登录认证记住我实例</h1> <div > <p>  | 登录用户:  | 角色:  | <a th:href="@{/logout}">退出登录</a>  </p> </div></div></body></html>

 

Web页面富含八个简易的视图:index主页和“hello”页面,都定义在Thymeleaf模板中。

4.1 修改login.html,在原基础上加多记住笔者复选框
<!DOCTYPE html><html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"><head> <meta charset="UTF-8"> <title>登录页面</title></head><body><h1>登录页面</h1><div th:if="${param.error}"> 用户名或密码不正确</div><div th:if="${param.logout}"> 你已经退出登录</div><form th:action="@{/login}" method="post"> <div><label> 用户名: <input type="text" name="username"/> </label></div> <div><label> 密&nbsp;&nbsp;&nbsp;码: <input type="password" name="password"/> </label></div> <div> <input name="remember-me" type="checkbox"/> 记住我 <input type="submit" value="登录"/> </div></form></body></html>

路径:src/main/resources/templates/index.html

二、修改TemplateConfig.java类路径:src/java/com/bootcap/session/security/configuration/TemplateConfig.java

6.3 点击跳转到hello页面链接,无需任何注明就能够实行跳转

图片 4image

: 为啥要接纳@ComponentScan注明:

  • 若果你的其他包都在运用了@SpringBootApplication注脚的main方法所在的包及其下属包,则SpringBoot会自动帮你把别的包都围观。
  • 即便您有一点bean所在的包,不在@SpringBootApplication表明main方法的包及其属下包,那么您要求手动加上@ComponentScan注脚并点名要研究的bean所在的包路线。(详见上述代码中package的不相同之处)

在上述的多个视图中,我们意在在做客"/hello"时需求报到本事够踏入Hello页面。此时大家得以由此Spring Security来兑现。(若是Spring Security在类路线上,则Spring Boot会选用"Basic"认证活动爱抚有着HTTP央求,也能够自定义设置)

<dependencies> ... <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> ...</dependencies>

路径:src/main/java/com/bootcap/session/security/configuration/WebSecurityConfig.java

package com.bootcap.session.security.configuration;import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;import org.springframework.security.config.annotation.web.builders.HttpSecurity;import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;@Configuration@EnableWebSecuritypublic class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/","/index").permitAll() // permitAll被允许访问 .anyRequest().authenticated() // 其余的请求需要认证后才可允许访问 .and() .formLogin() .loginPage .permitAll .logout() .permitAll(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() // 在内存中进行身份验证 .withUser .password("password") .roles; }}

:

  • WebSecurityConfig类使用了@EnableWebSecurity评释,以启用Spring Security的Web安全接济。

  • configure(HttpSecurity)方法自定义有哪些url供给被注明,哪些没有须要。当顾客登入后将会被重定向供给到须求居民身份表明的页面(hello.html),不然在客户未登入的动静下将会跳转到登入页面

  • configure(AuthenticationManagerBuilder)方法用于安装验证的尺度保存于内部存款和储蓄器中,客商名字为“user”,密码为“123456”,角色为User。同时该措施也能够修改认证方法为jdbc实行认证

: 使用了Spring Boot 2.0上述的Security会存在There is no PasswordEncoder mapped for the id "null"极度,施工方案见尾部“常见难题”

路径:src/main/resources/templates/login.html

<!DOCTYPE html><html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"><head> <meta charset="UTF-8"> <title>登录页面</title></head><body><div th:if="${param.error}"> 用户名或密码不正确</div><div th:if="${param.logout}"> 你已经退出登录</div><form th:action="@{/login}" method="post"> <div><label> 用户名: <input type="text" name="username"/> </label></div> <div><label> 密&nbsp;&nbsp;&nbsp;码: <input type="password" name="password"/> </label></div> <div><input type="submit" value="登录"/></div></form></body></html>

:

  • 该登录页面会将顾客名和密码以表单情势提交到"/login"。

  • 在Spring Security提供了二个梗阻诉求并证实的过滤器,在顾客未经过认证的意况下会重定向到"/login?error",而且展现相应的错误音信。注销成功后,Spring Security会将地址重定向到"/login?logout",大家即可在页面中来占卜应的登出新闻

在证实成功后跳转到hello.html页面,大家期望能够见到登入的客户名,同一时候同意客户退出登入,由此大家须求修改hello.html页面

路径:src/main/resources/templates/hello.html

<!DOCTYPE html><html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"><head> <meta charset="UTF-8"> <title>Hello</title></head><body> <h1 th:inline="text">Hello [[${#httpServletRequest.remoteUser}]]</h1> <form th:action="@{/logout}" method="post"> <input type="submit" value="退出登录" /> </form></body></html>

:

  • 大家在hello.html页面中央银行使了HttpServletRequest#getRemoteUser()的thymeleaf集成来展现客户名。

  • 页面中脱离登陆表单会将呼吁提交到"/logout",成功注销后前后相继会重定向到"/login?logout"。

由此小说刚领头的 【配置Spring Boot运营类】模块运营应用程序,这里不再过多介绍。

四、修改页面文件路线:src/resources/templates/

8.2 点击跳转到hello.html页面,会发掘并未有认证不容许步入,程序自动跳转到登陆页

图片 5image

三、修改WebSecurityConfig.java路径:src/java/com/bootcap/session/security/configuration/WebSecurityConfig.java

: 使用thymeleaf时索要在<html>标签前边出席xmlns="" xmlns:th="" 属性,技艺被编写翻译器深入分析为thymeleaf模板

5.1 项目运转成功后,浏览器访谈:localhsot:8080,会自动跳到登陆页面进行登入,并勾选记住作者。

图片 6

项目代码:

<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <name>spring-security-study-session</name> <groupId>com.bootcap.session.security</groupId> <artifactId>spring-security-study-session</artifactId> <version>1.0.0-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.1.RELEASE</version> </parent> <properties> <java.version>1.8</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> </properties> <dependencies> <!-- Spring Boot--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <!-- Test --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build></project>

Spring Security是八个功用强大且中度可定制的身份验证和访问调控框架。它实际是保证基于spring的应用程序的专门的学业,也是三个小心于向Java应用程序提供身份验证和授权的框架。连接:Spring Security

种类代码:

pom.xml中引入相关jar
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.1.RELEASE</version></parent><properties> <java.version>1.8</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding></properties><dependencies> ... <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> </dependency>...<dependencies>

: 本文以 IDEA 和 maven 以致Spring Boot 2.0 为例进行学科

6.1 到了这一步,大家必要将项目运作查看是不是一点差距也未有常,才开展下一步操作,由此需求配置spring boot启动类

路径:src/main/java/com/bootcap/session/security/app/Application.java

package com.bootcap.session.security.app;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.context.annotation.ComponentScan;@SpringBootApplication@ComponentScan(basePackages = {"com.bootcap.session.security"})public class Application { public static void main(String[] args) { SpringApplication.run(Application.class,args); }}
<!DOCTYPE html><html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"><head> <meta charset="UTF-8"> <title>Spring Security Index</title></head><body> <h1>Index Page</h1> <a th:href="@{/hello}">点击前往hello页面</a></body></html>
8.6 最终大家点击退出登陆,就能够到位注销操作(此时地方栏"/login?logout",并且跳回登入页面提示"你已经脱离登陆")

图片 7image

恭贺!你早已支付了三个简练的Spring Security程序。

在测量试验中,大家例行登入时候出现了要命:java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"

:通过难点大家驾驭该非常来自认证消息WebSecurityConfig的措施configure(AuthenticationManagerBuilder)。所以大家查阅官方文书档案,开采在spring boot 2.0以上使用的是Spring Security 5.0本子,同不平时候也提议运用密码校验时候要求开展密码加密。

故此,改变如下:

方法1:在Application.java启动类下加入该方法,关闭密码加密校验. @Bean public static PasswordEncoder passwordEncoder() { return NoOpPasswordEncoder.getInstance(); } 方法2:在WebSecurityConfig.java类的configure(AuthenticationManagerBuilder)进行如下改动 @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception {// auth.inMemoryAuthentication() // 在内存中进行身份验证// .withUser// .password("password")// .roles; auth.inMemoryAuthentication() // 在内存中进行身份验证 .passwordEncoder(new BCryptPasswordEncoder .withUser .password(new BCryptPasswordEncoder().encode) .roles; // auth.userDetailsService(userService).passwordEncoder(new BCryptPasswordEncoder; }

在大家付出的历程中,大家平时会超出修改一丝丝东西时候,都亟需重启操作来收效。由此,spring boot为大家提供了一个devTool热更新工具,无需重启就可以以预知效

<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <name>spring-security-study-session</name> <groupId>com.bootcap.session.security</groupId> <artifactId>spring-security-study-session</artifactId> <version>1.0.0-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.1.RELEASE</version> </parent> <properties> <java.version>1.8</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build></project>

在pom.xml文件中引进相关的jar包(不含security)

# 端口号server: port: 8080spring: # thymeleaf配置 thymeleaf: enabled: true encoding: UTF-8 mode: HTML servlet: content-type: text/html prefix: classpath:/templates/ suffix: .html
8.5 极度消除后大家再拓宽测量检验已经足以健康地跳转到hello.html页面,并展现了登入的顾客名

图片 8image

8.4 上面大家输入正确的账号登入(顾客名:user,密码:123456)

咱俩会开掘在调控台出现了十三分(实施方案:详见尾巴部分

图片 9image

<!DOCTYPE html><html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"><head> <meta charset="UTF-8"> <title>Hello</title></head><body> <h1>Hello Spring Security</h1></body></html>
  • JDK ≥1.7
  • Maven 3.0+
  • IntelliJ IDEA/eclipse
6.2 运营main方法,并在浏览器地址栏输入: 就算见到index.html页面,表明已经成功运维

图片 10image

鉴于Web应用程序基于Spring MVC。 因而,必要安顿视图调整器来暴露这几个模板。

路径:src/main/java/com/bootcap/session/security/configuration/TemplateConfig.java

package com.bootcap.session.security.configuration;import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configurationpublic class TemplateConfig implements WebMvcConfigurer { @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController.setViewName; registry.addViewController.setViewName; registry.addViewController.setViewName; registry.addViewController.setViewName; }}
8.1 应用运营后, 在浏览器中访问 . 就能访谈到Index页面

图片 11image

本文由永利皇宫463登录发布于编程,转载请注明出处:简单的登录认证,基于登录认证记住我实例

关键词: