栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringBoot项目——配置Mysql与注册登录模块

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringBoot项目——配置Mysql与注册登录模块

SpringBoot项目——配置Mysql与注册登录验证

回顾:
SpringBoot项目——创建菜单与游戏页面
SpringBoot项目——配置git环境与项目创建


文章目录
      • SpringBoot项目——配置Mysql与注册登录验证
      • 1. 配置 MySQL,创建所需数据库
      • 2. 配置 SpringBoot 操控 MySQL
          • 2.1 安装依赖
          • 2.2 SpringBoot 框架基本结构
          • 2.3 SpringBoot 代码介绍
          • 2.4 SpringBoot 主要注解介绍
      • 3. 修改Spring Security,实现 session 登录授权机制
          • 3.1 密码明文验证
          • 3.2 密码是密文(经过加密算法加密)时如何实现?

1. 配置 MySQL,创建所需数据库

mysql基本命令

  • 启动:net start mysql80;

  • 关闭:net stop mysql80;

  • 连接:mysql -uroot -p 链接用户名为root,密码为123456的数据库服务;

  • 退出:exit

  • 列出所有数据库:show databases;

  • 创建数据库:create database kob;

  • 删除数据库:drop database kob;

  • 使用数据库kob:use kob;

  • 列出当前数据库的所有表:show tables;

  • 创建名称为user的表,表中包含id和username两个属性:create table user(id int, username varchar(100))

  • 删除表:drop table user;

  • 在表中插入数据:insert into user values(1, ' ');

  • 查询表中数据:select * from user where id=2;

  • 删除某行数据:delete from user where id = 2;


2. 配置 SpringBoot 操控 MySQL 2.1 安装依赖
  • Maven仓库地址

  • Mybatis-Plus官网

  • 在pom.xml文件中添加依赖:

    • Spring Boot Starter JDBC ——用数据库
    • Project Lombok —— 自动写好通用方法,包括set、get、toString、equal、hashCode方法
    • MySQL Connector/J
    • mybatis-plus-boot-starter —— MyBatis Plus 写好mapper层sql语句
    • mybatis-plus-generator

    • spring-boot-starter-security —— 实现登录授权机制

    • jjwt-api

    • jjwt-impl

    • jjwt-jackson

  • 在application.properties中添加数据库配置:

    spring.datasource.username=root
    spring.datasource.password=123456
    spring.datasource.url=jdbc:mysql://localhost:3306/kob?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8
    spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
    
2.2 SpringBoot 框架基本结构
  • pojo层:将数据库中的表对应成Java中的Class

  • mapper层(Dao层):数据访问层,将pojo层的class中的操作,映射成sql语句

  • service层:业务逻辑层,写具体的业务逻辑,组合使用mapper中的操作

  • controller层:调度service,负责请求转发,接受页面过来的参数,传给Service处理,接到返回值,再传给页面

  • 类似 SpringMVC、三层架构。

2.3 SpringBoot 代码介绍

SpringBoot入口: 启动SpringBoot应用,SpringApplication.run。

package com.kob.backend;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class BackendApplication {
    public static void main(String[] args) {
        SpringApplication.run(BackendApplication.class, args);
    }
}

pojo层: com.kob.backend.pojo.User.class

package com.kob.backend.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

// 加入依赖的注解后可帮助写Set、Get、toString等方法。
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private Integer id;
    private String username;
    private String password;
}

mapper层: com.kob.backend.mapper.UserMapper.class

package com.kob.backend.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.kob.backend.pojo.User;
import org.apache.ibatis.annotations.Mapper;

@Mapper
// mybatisplus 帮助写sql语句
public interface UserMapper extends BaseMapper {

}

service层:

// 目前业务逻辑较简单,直接写在了Controller层

controller层: package com.kob.backend.controller.user.UserController.class

package com.kob.backend.controller.user;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.kob.backend.mapper.UserMapper;
import com.kob.backend.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class UserController {
    @Autowired // 如果要用到数据库接口的mapper的话,需要加此注解
    UserMapper userMapper;

    // @RequestMapping会将所有请求映射,也可指明类型。
    // @GetMapping映射Get类型请求。@PostMapping会映射Post类型请求

    // 查询所有
    @GetMapping("/user/all/")
    public List getAll() {
        return userMapper.selectList(null); //null表示查询所有的
    }

    // 按id查找
    @GetMapping("/user/{userId}/")
    public List getUser(@PathVariable int userId){ //@PathVariable 映射 URL 绑定的占位符
        // 按id查找
        QueryWrapper queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id",2);
        return userMapper.selectList(queryWrapper);
        // 上面三行等价与直接return userMapper.selectById(userId);
    }

    // 插入
    @GetMapping("/user/add/{userId}/{username}/{password}/")
    public String addUser(@PathVariable int userId,
                          @PathVariable String username,
                          @PathVariable String password){
        User user = new User(userId, username, password);
        userMapper.insert(user);
        return "Add User Successfully!";
    }

    // 按id删除
    @GetMapping("/user/delete/{userId}")
    public String deleteUser(@PathVariable int userId){
        userMapper.deleteById(userId);
        return "Delete User Successfully!";
    }
}
2.4 SpringBoot 主要注解介绍
  • @RestController注解

    • @RestController = @Controller + @ResponseBody。将java对象转为json格式的数据,后端通过api将json数据传到前端

    • 代表返回的是json格式的数据,这个注解是Spring4之后新加的注解,原来返回json格式的数据需要@ResponseBody配合@Controller一起使用;

    • 如果我们在项目中使用的是@Conrtroller注解的话,不加@Response注解,则当直接返回一个字符串的时候,就好比返回的是一个模板页面,类似我们返回一个jsp页面一样。所以我们需要加上模板引擎。(这种返回html一类的模板的开发方式现在一般不会再用了,因为现在都是前后端分离式的开发,后台服务器一般只需要返回json格式的数据即可,所以了解即可)

  • @Autowired 如果要用到数据库接口的mapper的话,需要加此注解

  • @RequestMapping 会将所有请求映射,也可指明类型。

    • @GetMapping映射Get类型请求。
    • @PostMapping映射Post类型请求
  • @PathVariable 映射 URL 绑定的占位符


3. 修改Spring Security,实现 session 登录授权机制
  • 装依赖 spring-boot-starter-security

验证过程: 登录时用户端输入用户名密码,后端查找数据库,若存在且密码一致则返回给用户端sessionID。sessionID存在本地cookie里,登录成功后,每次访问后端数据库都会自动将sessionID传递进去验证,一段时间内有效,过期需要再次登陆验证。数据库通过sessionId对应信息。

3.1 密码明文验证

  • 编写service.impl.UserDetailsServiceImpl类,继承自UserDetailsService接口,用来接入数据库信息。所写loadUserByUsername方法,按用户名查找。
    UserDetailsService 接口用来接入数据库信息,从数据库中获取信息。

  • 如果想让security对接自己写的数据库,需要把username在数据库中对应的的用户找出来,返回他的密码(这里的数据库存储中指明明文{noop}),需要用到数据库操作mapper,能写private就写private,用数据库记得加上autowired.

    package com.kob.backend.service.impl;
    
    import ...;
    
    // 实现service.impl.UserDetailsServiceImpl类,继承自UserDetailsService接口
    // UserDetailsService 用来接入数据库信息,从数据库中获取信息。
    // 调用loadUserByUsername,按用户名查找。
    @Service
    public class UserDetailsServiceImpl implements UserDetailsService {
    
        @Autowired
        private UserMapper userMapper;
        @Override
        // 传入用户名,返回用户名和密码(要求数据库中用户名唯一)
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
            QueryWrapper queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("username",username);
            User user = userMapper.selectOne(queryWrapper);
            if(user == null){
                throw new RuntimeException("用户不存在");
            }
            return new UserDetailsImpl(user);
        }
    }
    

    UserDetails介绍: 这个接口代表了最详细的用户信息,这个接口涵盖了一些必要的用户信息字段,具体的实现类对它进行了扩展。 它和Authentication接口很类似,比如它们都拥有username,authorities。
    Authentication的getCredentials()与UserDetails中的getPassword()需要被区分对待,前者是用户提交的密码凭证,后者是用户正确的密码,认证器其实就是对这两者的比对。Authentication中的getAuthorities()实际是由UserDetails的getAuthorities()传递而形成的。Authentication接口中的getUserDetails()方法吗,其中的UserDetails用户详细信息便是经过了AuthenticationProvider之后被填充的

    package com.kob.backend.service.impl.utils;
    
    import ...
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class UserDetailsImpl implements UserDetails {
    
        private User user;
    
        @Override
        public Collection getAuthorities() {
            return null;
        }
    
        @Override
        public String getPassword() {
            return user.getPassword(); // 返回User中user的password
        }
    
        @Override
        public String getUsername() {
            return user.getUsername(); // 返回User中user的name
        }
    
        // 是否没被锁定
        @Override
        public boolean isAccountNonExpired() {
            return true;
        }
    
        // 是否没被锁定
        @Override
        public boolean isAccountNonLocked() {
            return true;
        }
    
        // 授权是否过期
        @Override
        public boolean isCredentialsNonExpired() {
            return true;
        }
    
        // 用户是否被启用
        @Override
        public boolean isEnabled() {
            return true;
        }
    }
    
3.2 密码是密文(经过加密算法加密)时如何实现?

若数据库中所存密码是P1,加密后是SP1。每次将输入的密码P2,加密成SP2,看与SP是否匹配来验证登录。即无序知道具体内容,只需知道是否匹配即可。
测试如下:

  • 实现config.SecurityConfig类,用来实现用户密码的加密存储,此时数据库中需要存密文,而非明文。

    package com.kob.backend.config;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
    import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    import org.springframework.security.crypto.password.PasswordEncoder;
    
    @Configuration
    @EnableWebSecurity
    public class SecurityConfig {
        @Bean
        public PasswordEncoder passwordEncoder() {
        	// 返回所用加密方法(包括明文转密文,明文跟密文是否匹配)
            return new BCryptPasswordEncoder();
        }
    }
    
  • 注册插入用户信息时,便可以实现密码存储为密文
    修改UserController中插入用户函数:

    // 插入
    @GetMapping("/user/add/{userId}/{username}/{password}/")
    public String addUser(@PathVariable int userId,
                          @PathVariable String username,
                          @PathVariable String password){
        PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();//指明编码方式
        String encodePassword = passwordEncoder.encode(password);
        User user = new User(userId, username, encodePassword);
        userMapper.insert(user);
        return "Add User Successfully!";
    }
    

    结果如下:

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1036188.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号