<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Springboot+Shiro+Mybatis+mysql實現權限安全認證

      Shiro是Apache 的一個強大且易用的Java安全框架,執行身份驗證、授權、密碼學和會話管理。Shiro 主要分為兩個部分就是認證和授權兩部分

      一、介紹

      1. Subject代表了當前用戶的安全操作

      2. SecurityManager:它是Shiro框架的核心,典型的Facade模式,Shiro通過SecurityManager來管理內部組件實例,并通過它來提供安全管理的各種服務。

      3. Authenticator即認證器,對用戶身份進行認證,Authenticator是一個接口,shiro提供ModularRealmAuthenticator實現類,通過ModularRealmAuthenticator基本上可以滿足大多數需求,也可以自定義認證器。

      4. Authorizer即授權器,用戶通過認證器認證通過,在訪問功能時需要通過授權器判斷用戶是否有此功能的操作權限。

      5. Realm充當了Shiro與應用安全數據間的“橋梁”或者“連接器”。也就是說,當對用戶執行認證(登錄)和授權(訪問控制)驗證時,Shiro會從應用配置的Realm中查找用戶及其權限信息。

      6. sessionManager即會話管理,shiro框架定義了一套會話管理,它不依賴web容器的session,所以shiro可以使用在非web應用上。

      Shiro相關類介紹

      • (1)Authentication 認證 —— 用戶登錄

      • (2)Authorization 授權 —- 用戶具有哪些權限

      • (3)Cryptography 安全數據加密

      • (4)Session Management 會話管理

      • (5)Web Integration web系統集成

      • (6)Interations 集成其它應用,spring、緩存框架

      二、依賴引入

      完整的pom文件如下:

      <?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/xsd/maven-4.0.0.xsd">
      	<modelVersion>4.0.0</modelVersion>
      	<parent>
      		<groupId>org.springframework.boot</groupId>
      		<artifactId>spring-boot-starter-parent</artifactId>
      		<version>2.4.1</version>
      		<relativePath></relativePath> <!-- lookup parent from repository -->
      	</parent>
      	<groupId>com.gt.shiro</groupId>
      	<artifactId>com.sunyue.shiro</artifactId>
      	<version>1.0-SNAPSHOT</version>
      	<packaging>jar</packaging>
      	<properties>
      		<java.version>1.8</java.version>
      		<druid.verzion>1.1.10</druid.verzion>
      		<pagehelper.version>1.2.10</pagehelper.version>
      		<mybatis.version>2.1.4</mybatis.version>
      		<thymeleaf-layout-dialect.version>2.0.4</thymeleaf-layout-dialect.version>
      	</properties>
      	<dependencies>
      		<dependency>
      			<groupId>org.springframework.boot</groupId>
      			<artifactId>spring-boot-starter-web</artifactId>
      			<!-- 排除默認的tomcat -->
      			<exclusions>
      				<exclusion>
      					<groupId>org.springframework.boot</groupId>
      					<artifactId>spring-boot-starter-tomcat</artifactId>
      				</exclusion>
      			</exclusions>
      		</dependency>
      		<!-- 重新依賴Jetty的starter -->
      		<dependency>
      			<groupId>org.springframework.boot</groupId>
      			<artifactId>spring-boot-starter-jetty</artifactId>
      		</dependency>
      		<dependency>
      			<groupId>org.mybatis.spring.boot</groupId>
      			<artifactId>mybatis-spring-boot-starter</artifactId>
      			<version>${mybatis.version}</version>
      		</dependency>
      		<dependency>
      			<groupId>org.springframework.boot</groupId>
      			<artifactId>spring-boot-starter-thymeleaf</artifactId>
      		</dependency>
      		<dependency>
      			<groupId>com.github.theborakompanioni</groupId>
      			<artifactId>thymeleaf-extras-shiro</artifactId>
      			<version>2.0.0</version>
      		</dependency>
      		<!--shiro整合spring-->
      		<dependency>
      			<groupId>org.apache.shiro</groupId>
      			<artifactId>shiro-spring</artifactId>
      			<version>1.4.0</version>
      		</dependency>
      		<dependency>
      			<groupId>com.alibaba</groupId>
      			<artifactId>druid-spring-boot-starter</artifactId>
      			<version>${druid.verzion}</version>
      		</dependency>
      		<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper-spring-boot-starter -->
      		<dependency>
      			<groupId>com.github.pagehelper</groupId>
      			<artifactId>pagehelper-spring-boot-starter</artifactId>
      			<version>${pagehelper.version}</version>
      		</dependency>
      		<dependency>
      			<groupId>mysql</groupId>
      			<artifactId>mysql-connector-java</artifactId>
      			<scope>runtime</scope>
      		</dependency>
      		<dependency>
      			<groupId>org.projectlombok</groupId>
      			<artifactId>lombok</artifactId>
      			<optional>true</optional>
      		</dependency>
      		<dependency>
      			<groupId>org.springframework.boot</groupId>
      			<artifactId>spring-boot-starter-test</artifactId>
      			<scope>test</scope>
      		</dependency>
      	</dependencies>
      	<build>
      		<plugins>
      			<!-- spring boot maven插件 -->
      			<plugin>
      				<groupId>org.springframework.boot</groupId>
      				<artifactId>spring-boot-maven-plugin</artifactId>
      				<configuration>
      					<mainClass>com.gt.shiro.SpringShiroApplication</mainClass>
      				</configuration>
      			</plugin>
      		</plugins>
      	</build>
      </project>
      

      三、配置文件

      application.yml配置文件:
      # 開發時關閉緩存,不然沒法看到實時頁面
      spring.thymeleaf.cache=false
      # 用非嚴格的 HTML
      spring.thymeleaf.mode=HTML
      spring.thymeleaf.encoding=utf-8
      spring.thymeleaf.servlet.content-type=text/html
      spring.datasource.druid.url=jdbc:mysql://localhost:3306/shiro?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
      spring.datasource.druid.username=root
      spring.datasource.druid.password=admin
      spring.datasource.druid.initial-size=1
      spring.datasource.druid.min-idle=1
      spring.datasource.druid.max-active=20
      spring.datasource.druid.test-on-borrow=true
      #springbootjdbc導入包不和以前一樣
      spring.datasource.druid.driver-class-name= com.mysql.cj.jdbc.Driver
      mybatis.type-aliases-package=com.gt.shiro.entity
      mybatis.mapper-locations=classpath:mapper/*.xml
      #打印數據庫的操作
      logging.level.com.example.springsecurity.dao=debug
      #redis緩存
      ### 配置Redis
      mybatis.configuration.cache-enabled=true
      # Redis數據庫索引(默認為0)
      spring.redis.database=0
      # Redis服務器地址
      spring.redis.host=...
      # Redis服務器連接端口
      spring.redis.port=6379
      # Redis服務器連接密碼(默認為空)
      spring.redis.password=sunyue
      # 連接池最大連接數(使用負值表示沒有限制)
      spring.redis.jedis.pool.max-idle=200
      # 連接池最大阻塞等待時間(使用負值表示沒有限制)
      spring.redis.jedis.pool.max-wait=-1
      # 連接池中的最小空閑連接
      spring.redis.jedis.pool.min-idle=0
      # 連接超時時間(毫秒)
      spring.redis.timeout=1000
      

      Shiro兩個重要的配置類:

      • 1.UserRealm

          package com.gt.shiro.config;
          import com.gt.shiro.entity.TestUser;
          import com.gt.shiro.server.TestUserServer;
          import org.apache.shiro.SecurityUtils;
          import org.apache.shiro.authc.*;
          import org.apache.shiro.authz.AuthorizationInfo;
          import org.apache.shiro.authz.SimpleAuthorizationInfo;
          import org.apache.shiro.realm.AuthorizingRealm;
          import org.apache.shiro.subject.PrincipalCollection;
          import org.apache.shiro.subject.Subject;
          import org.springframework.beans.factory.annotation.Autowired;
          import java.util.ArrayList;
          import java.util.HashSet;
          import java.util.List;
          import java.util.Set;
          public class UserRealm extends AuthorizingRealm {
          	@Autowired
          	private TestUserServer testUserServer;
          	/**
          	 * 執行授權邏輯
          	 *
          	 * @param principalCollection
          	 * @return
          	 */
          	@Override
          	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
          		System.out.println("執行授權邏輯");
          		/*獲取當前登錄的用戶信息*/
          		Subject subject = SecurityUtils.getSubject();
          		TestUser testUser = (TestUser) subject.getPrincipal();
          		//設置角色,多個角色
          		/*Set<String> rolesSet = new HashSet<>();
          		rolesSet.add(testUser.getRole());*/
          		//SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(rolesSet);
          		//給資源進行授權
          		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
          		/*可以在以下list加入多個權限*/
          		/*List<String> roles = new ArrayList<>();
          		roles.add(testUser.getPerms());
          		info.addRoles(roles);*/
          		//設置權限
          		info.addRole(testUser.getRole());
          		//需要判斷權限是否為空值(null是沒有地址,""是有地址但是里面的內容是空的)
          		if (testUser.getPerms() != null && !testUser.getPerms().equals("")) {
          			info.addStringPermission(testUser.getPerms());
          		}
          		return info;
          	}
          	/**
          	 * 執行認證邏輯
          	 *
          	 * @param authenticationToken
          	 * @return
          	 * @throws AuthenticationException
          	 */
          	@Override
          	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
          		System.out.println("執行認證邏輯");
          		/*獲取令牌*/
          		UsernamePasswordToken passwordToken = (UsernamePasswordToken) authenticationToken;
          		//取出用戶名并且判斷用戶名是否和數據庫一致
          		TestUser testUser = testUserServer.selectOneByName(passwordToken.getUsername());
          		if (testUser != null) {
          			//進行認證,將正確數據給shiro處理
          			//密碼不用自己比對,AuthenticationInfo認證信息對象,一個接口,new他的實現類對象SimpleAuthenticationInfo
          			/*    第一個參數隨便放,可以放user對象,程序可在任意位置獲取 放入的對象
          			 * 第二個參數必須放密碼,
          			 * 第三個參數放 當前realm的名字,因為可能有多個realm*/
          			//若密碼不正確則返回IncorrectCredentialsException異常
          			return new SimpleAuthenticationInfo(testUser, testUser.getPassword(), this.getName());
          		}
          		//若用戶名不存在則返回UnknownAccountException異常
          		return null;
          	}
          }
        
      • 2.ShiroConfig

          package com.gt.shiro.config;
          import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
          import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
          import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
          import org.apache.shiro.mgt.SecurityManager;
          import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
          import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
          import org.springframework.beans.factory.annotation.Qualifier;
          import org.springframework.context.annotation.Bean;
          import org.springframework.context.annotation.Configuration;
          import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;
          import java.util.LinkedHashMap;
          import java.util.Map;
          import java.util.Properties;
          @Configuration
          public class ShiroConfig {
          	@Bean
          	public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager) {
          		ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
          		//設置安全管理器
          		shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
          		//添加一些Shiro的內置過濾器
          		/**
          		 * Shiro 的內置過濾器可以實現權限的相關攔截
          		 * 常用過濾器
          		 * 1.anon:無需認證
          		 * 2.authc:必須認證才能訪問
          		 * 3.user:如果使用rememberme功能可以訪問
          		 * 4.perms:對應權限才能訪問
          		 * 5.role:對應角色才能訪問
          		 */
          		//登錄狀態下才可以訪問main頁面,manage權限可訪問manage頁面,admin角色可訪問admin頁面
          		Map<String, String> filterMap = new LinkedHashMap<String, String>();
          		filterMap.put("/main", "authc");
          		filterMap.put("/manage", "perms[manage]");
          		filterMap.put("/admin", "roles[admin]");
          		shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
          		//未登錄狀態下訪問將跳轉至login頁面
          		// 如果不設置默認會自動尋找Web工程根目錄下的"/login.jsp"頁面
          		shiroFilterFactoryBean.setLoginUrl("/login");
          		// 登錄成功后要跳轉的鏈接
          		shiroFilterFactoryBean.setSuccessUrl("/");
          		//無授限狀態下訪問將請求unauthor
          		shiroFilterFactoryBean.setUnauthorizedUrl("/unAuth");
          		return shiroFilterFactoryBean;
          	}
          	@Bean(name = "securityManager")
          	public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm) {
          		DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
          		//DefaultWebSecurityManager需要關聯一個Realm
          		defaultWebSecurityManager.setRealm(userRealm);
          		return defaultWebSecurityManager;
          	}
          	/**
          	 * 創建realm
          	 */
          	@Bean(name = "userRealm")
          	public UserRealm getRealm() {
          		return new UserRealm();
          	}
          	@Bean
          	public ShiroDialect shiroDialect() {
          		return new ShiroDialect();
          	}
          	/**
          	 * 開啟Shiro的注解(如@RequiresRoles,@RequiresPermissions)
          	 * 配置以下兩個bean(DefaultAdvisorAutoProxyCreator和AuthorizationAttributeSourceAdvisor)即可實現此功能
          	 *
          	 * @return
          	 */
          	@Bean
          	public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {
          		DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
          		advisorAutoProxyCreator.setProxyTargetClass(true);
          		return advisorAutoProxyCreator;
          	}
          	/**
          	 * 開啟 shiro 的@RequiresPermissions注解
          	 *
          	 * @param securityManager
          	 * @return
          	 */
          	@Bean
          	public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
          		AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
          		authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
          		return authorizationAttributeSourceAdvisor;
          	}
          	/**
          	 * shiro出現權限異常可通過此異常實現制定頁面的跳轉(或接口跳轉)
          	 *
          	 * @return
          	 */
          	@Bean
          	public SimpleMappingExceptionResolver simpleMappingExceptionResolver() {
          		SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
          		Properties properties = new Properties();
          		/*未授權處理頁*/
          		properties.setProperty("org.apache.shiro.authz.UnauthorizedException", "/error.html");
          		/*身份沒有驗證*/
          		properties.setProperty("org.apache.shiro.authz.UnauthenticatedException", "/error.html");
          		resolver.setExceptionMappings(properties);
          		return resolver;
          	}
          }
        

      四、數據連接和業務邏輯

      • 1.實體類

          package com.gt.shiro.entity;
          import lombok.Data;
          import lombok.experimental.Accessors;
          import java.io.Serializable;
          import java.util.Date;
          @Data
          @Accessors(chain = true)
          public class TestUser implements Serializable {
          	private Integer id;
          	private String username;
          	private String password;
          	/*權限*/
          	private String perms;
          	/*角色*/
          	private String role;
          	/*加鹽密碼*/
          	private String salt;
          }
        
      • 2.Dao和Mapper

          package com.gt.shiro.dao;
          import com.gt.shiro.entity.TestUser;
          import org.apache.ibatis.annotations.Mapper;
          import java.util.List;
          @Mapper
          public interface TestUserMapper {
          	List<TestUser> findAll();
          	TestUser selectOne(Integer id);
          	TestUser selectOneByName(String username);
          	void insert(TestUser testUser);
          	void update(TestUser testUser);
          	void delete(Integer id);
          }
        

      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
      <mapper namespace="com.gt.shiro.dao.TestUserMapper">
      	<select id="findAll"  resultType="TestUser">
      	   select * from test_user
      	</select>
      	<select id="selectOne" resultType="TestUser">
      	   select * from test_user where id=#{id}
      	</select>
      	<select id="selectOneByName" resultType="TestUser">
      	   select * from test_user where username=#{username}
      	</select>
      	<insert id="insert">
      		insert into test_user (id,username,password,perms,role,salt) value (#{id},#{username},#{password},#{perms},#{role},#{salt})
      	</insert>
      	<update id="update">
      		update test_user set username = #{username},password=#{password},perms=#{perms},role=#{role},salt=#{salt} where id = #{id}
      	</update>
      	<delete id="delete">
      		delete from test_user where id = #{id}
      	</delete>
      </mapper>
      
      • 3.業務層及其實現

          package com.gt.shiro.server;
          import com.gt.shiro.entity.TestUser;
          import org.springframework.stereotype.Service;
          import java.util.List;
          @Service
          public interface TestUserServer {
          	/*查詢所有*/
          	List<TestUser> selectAll();
          	/*查詢一個用戶*/
          	TestUser selectByOne(Integer id);
          	/*通過名字查詢一個用戶*/
          	TestUser selectOneByName(String name);
          	/*增加一個用戶*/
          	void insert(TestUser testUser);
          	/*刪除一個用戶*/
          	void delete(Integer id);
          	/*更新一個用戶*/
          	void update(TestUser testUser);
          }
        

      package com.gt.shiro.server.serverImpl;
      import com.gt.shiro.dao.TestUserMapper;
      import com.gt.shiro.entity.TestUser;
      import org.apache.shiro.crypto.SecureRandomNumberGenerator;
      import org.apache.shiro.crypto.hash.SimpleHash;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.stereotype.Service;
      import com.sunyue.shiro.server.TestUserServer;
      import java.util.List;
      @Service
      public class TestUserServerImpl implements TestUserServer {
      	@Autowired
      	private TestUserMapper testUserMapper;
      	@Override
      	public List<TestUser> selectAll() {
      		return testUserMapper.findAll();
      	}
      	@Override
      	public TestUser selectByOne(Integer id) {
      		return testUserMapper.selectOne(id);
      	}
      	@Override
      	public TestUser selectOneByName(String name) {
      		return testUserMapper.selectOneByName(name);
      	}
      	@Override
      	public void insert(TestUser testUser) {
      		//加密寫法
      		String salt = new SecureRandomNumberGenerator().nextBytes().toString();
      		String password= new SimpleHash("md5",testUser.getPassword(),salt,2).toString();
      		testUser.setPassword(password);
      		testUser.setSalt(salt);
      		testUserMapper.insert(testUser);
      	}
      	@Override
      	public void delete(Integer id) {
      		testUserMapper.delete(id);
      	}
      	@Override
      	public void update(TestUser testUser) {
      		testUserMapper.update(testUser);
      	}
      }
      
      • 4.控制層

          package com.gt.shiro.controller;
          import com.gt.shiro.entity.TestUser;
          import com.gt.shiro.server.TestUserServer;
          import org.apache.shiro.SecurityUtils;
          import org.apache.shiro.authc.IncorrectCredentialsException;
          import org.apache.shiro.authc.UnknownAccountException;
          import org.apache.shiro.authc.UsernamePasswordToken;
          import org.apache.shiro.crypto.hash.SimpleHash;
          import org.apache.shiro.subject.Subject;
          import org.springframework.beans.factory.annotation.Autowired;
          import org.springframework.stereotype.Controller;
          import org.springframework.ui.Model;
          import org.springframework.web.bind.annotation.*;
          @Controller
          public class indexController {
          	@Autowired
          	private TestUserServer testUserServer;
          	@GetMapping("/{url}")
          	public String redirect(@PathVariable("url") String url) {
          		return url;
          	}
          	@RequestMapping(value = {"/", "/index"}, method = RequestMethod.GET)
          	private String index() {
          		return "index";
          	}
          	@PostMapping("/login")
          	public String login(String username, String password, Model model) {
          		Subject subject = SecurityUtils.getSubject();
          		TestUser testUser = testUserServer.selectOneByName(username);
          		if (testUser != null) {
          			//根據salt值和用戶輸入的密碼計算加密后的密碼
          			String salt = testUser.getSalt();
          			password = new SimpleHash("md5", password, salt, 2).toString();
          			System.out.println(password);
          		}
          		UsernamePasswordToken token = new UsernamePasswordToken(username, password);
          		//UsernamePasswordToken token = new UsernamePasswordToken(username, testUser.getPassword());(不加密寫法)
          		try {
          			//將用戶名和密碼通過token傳給shiro進行認證
          			subject.login(token);
          			TestUser user = (TestUser) subject.getPrincipal();
          			subject.getSession().setAttribute("testUser", user);
          			return "index";
          		} catch (UnknownAccountException e) {
          			e.printStackTrace();
          			model.addAttribute("msg", "用戶名不存在");
          			return "login";
          		} catch (IncorrectCredentialsException e) {
          			e.printStackTrace();
          			model.addAttribute("msg", "密碼有誤");
          			return "login";
          		}
          	}
          	@ResponseBody
          	@GetMapping("/unauthor")
          	public String unauthor() {
          		return "權限不足,無法訪問";
          	}
          	@GetMapping("/logout")
          	public String logout() {
          		Subject subject = SecurityUtils.getSubject();
          		subject.logout();
          		return "login";
          	}
          	@PostMapping("/register")
          	public String register(TestUser testUser, Model model) {
          		String username = testUser.getUsername();
          		String password = testUser.getPassword();
          		if (username ** null || username.equals("")) {
          			model.addAttribute("msg", "用戶名不能為空");
          			return "register";
          		} else if (password ** null || password.equals("")) {
          			model.addAttribute("msg", "密碼不能為空");
          			return "register";
          		} else if (testUserServer.selectOneByName(username) != null) {
          			model.addAttribute("msg", "用戶名已被占用");
          			return "register";
          		} else {
          			testUserServer.insert(testUser);
          			return "login";
          		}
          	}
          }
        
      • 5.前端頁面

        • (1)index.html

            <!DOCTYPE html>
            <html xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.thymrleaf.org/thymeleaf-extras-shiro">
            <head>
            	<meta charset="UTF-8">
            	<title>Insert title here</title>
            	<link rel="shortcut icon" href="#"/>
            </head>
            <body>
            <div th:if="${session.testUser != null}">
            		<span th:text="'歡迎回來 '+${session.testUser.username}+'!  '">
            		</span><a href="/logout">退出</a>
            </div>
            <a href="/main">main</a>
            <span shiro:hasPermission="manage"> | <a href="/manage">manage</a></span>
            <span shiro:hasRole="admin"> | <a href="/admin">admin</a></span>
            <br>
            </body>
            </html>
          
        • (2)login.html

            <!DOCTYPE html>
            <html xmlns:th="http://www.thymeleaf.org">
            <head>
            	<meta charset="UTF-8">
            	<title>Insert title here</title>
            	<link rel="shortcut icon" href="#"/>
            </head>
            <body>
            <form action="/login" method="post">
            	<span th:text="${msg}" style="color: red"></span>
            	<table>
            		<tr>
            			<td>用戶名:</td>
            			<td><input type="text" name="username"/></td>
            		</tr>
            		<tr>
            			<td>密碼:</td>
            			<td><input type="password" name="password"/></td>
            		</tr>
            		<tr>
            			<td><input type="submit" value="登錄"/></td>
            			<td><a href="/register">
            				<button type="button" value="注冊">注冊</button>
            			</a>
            			</td>
            		</tr>
            	</table>
            </form>
            </body>
            </html>
          
        • (3)register.html

            <!DOCTYPE html>
            <html xmlns:th="http://www.thymeleaf.org">
            <head>
            	<meta charset="UTF-8">
            	<title>Insert title here</title>
            	<link rel="shortcut icon" href="#"/>
            </head>
            <body>
            <form action="/register" method="post">
            	<span th:text="${msg}" style="color: red"></span>
            	<table>
            		<tr>
            			<td>用戶名:</td>
            			<td><input type="text" name="username"/></td>
            		</tr>
            		<tr>
            			<td>密碼:</td>
            			<td><input type="password" name="password"/></td>
            		</tr>
            		<tr>
            			<td><input type="submit" value="注冊"/></td>
            		</tr>
            	</table>
            </form>
            </body>
            </html>
          
        • (4)main.html

            <!DOCTYPE html>
            <html>
            <head>
            	<meta charset="UTF-8">
            	<title>Insert title here</title>
            	<link rel="shortcut icon" href="#"/>
            </head>
            <body>
            <h1>main</h1>
            </body>
            </html>
          
        • (5)manage.html

            <!DOCTYPE html>
            <html>
            <head>
            	<meta charset="UTF-8">
            	<title>Insert title here</title>
            	<link rel="shortcut icon" href="#"/>
            </head>
            <body>
            <h1>manage</h1>
            </body>
            </html>
          
        • (6)admin.html

            <!DOCTYPE html>
            <html>
            <head>
            	<meta charset="UTF-8">
            	<title>Insert title here</title>
            	<link rel="shortcut icon" href="#"/>
            </head>
            <body>
            <h1>admin</h1>
            </body>
            </html>
          
      • 6.數據庫文件

          /*
          Navicat MySQL Data Transfer
          Source Server         : sunyue
          Source Server Version : 50724
          Source Host           : localhost:3306
          Source Database       : shiro
          Target Server Type    : MYSQL
          Target Server Version : 50724
          File Encoding         : 65001
          Date: 2021-01-11 22:00:47
          */
          SET FOREIGN_KEY_CHECKS=0;
          -- ----------------------------
          -- Table structure for test_user
          -- ----------------------------
          DROP TABLE IF EXISTS `test_user`;
          CREATE TABLE `test_user` (
            `id` int(11) NOT NULL AUTO_INCREMENT,
            `username` varchar(120) DEFAULT NULL,
            `password` varchar(120) DEFAULT NULL,
            `perms` varchar(120) DEFAULT NULL,
            `role` varchar(120) DEFAULT NULL,
            `salt` varchar(100) DEFAULT NULL,
            PRIMARY KEY (`id`)
          ) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4;
          -- ----------------------------
          -- Records of test_user
          -- ----------------------------
          INSERT INTO `test_user` VALUES ('4', 'admin', '4867df2e009d0096c4cd8d9be8cc104c', 'manage', 'admin', 'GQR2m1N1o3nSLjtOzMITRQ**');
          INSERT INTO `test_user` VALUES ('5', 'user', '636502f40cf197dd2f4b19f56f475b24', '', '', 'Kxw3HZiFmgnlUu8fmjMY7Q**');
          INSERT INTO `test_user` VALUES ('6', 'user1', '43f3133aa7e0ef9cf8373521dff8d8e8', 'manage', null, 'J8fn4HpauvNOrlUaRl/Spg**');
          INSERT INTO `test_user` VALUES ('7', '1', '1', 'manage', null, null);
        
      posted @ 2024-07-05 22:00  二價亞鐵  閱讀(818)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 亚洲男人的天堂av手机在线观看| 久久亚洲人成网站| 国产毛片子一区二区三区| 国产亚洲精品在天天在线麻豆| 欧美高清精品一区二区| 日韩精品亚洲专在线电影| 在线高清免费不卡全码| 久久夜色精品国产亚av| 无码av中文字幕久久专区| 国产在线午夜不卡精品影院| 精品偷自拍另类精品在线| √天堂中文www官网在线| 人妻换着玩又刺激又爽| 日韩中文日韩中文字幕亚| 人人妻人人做人人爽夜欢视频| 中文字幕日韩区二区三区| 亚洲国产午夜福利精品| 国产精品无码av不卡| 国产深夜福利在线免费观看| 好紧好爽午夜视频| 极品尤物被啪到呻吟喷水| 微拍福利一区二区三区| 日韩福利片午夜免费观着| 亚洲色大成网站WWW尤物| 中国女人熟毛茸茸A毛片| 国产精品第一页中文字幕| 国产成人综合95精品视频| 沽源县| 亚洲综合天堂一区二区三区| 伊人久久大香线蕉综合影院| 亚洲精品一二三四区| 欧美成人精精品一区二区三区| 69天堂人成无码免费视频| 欧美牲交a欧美牲交aⅴ一| 免费国产一区二区不卡| 久久人人97超碰国产精品| 人妻一区二区三区三区| 国产普通话对白刺激| 亚欧洲乱码视频一二三区| 最新国产精品拍自在线观看| 无码天堂亚洲国产av麻豆|