【JT后台管理开发文档】1_用户登陆退出操作
表设计user表设计字段名称数据类型是否为空备注idintN用户编号,PK主键usernamevarchar(80)Y用户名passwordvarchar(80)Y登录密码 加密之后的密文 加密APIphonevarchar(20)Y手机号emailvarchar(40)Y邮箱statustinyintY0-1 布尔类型值 0-false 1-true 启用还是禁用createddatetimeY
用户登陆退出操作
1. user表设计
字段名称 | 数据类型 | 是否为空 | 备注 |
---|---|---|---|
id | int | N | 用户编号,PK主键 |
username | varchar(80) | Y | 用户名 |
password | varchar(80) | Y | 登录密码 加密之后的密文 加密API |
phone | varchar(20) | Y | 手机号 |
varchar(40) | Y | 邮箱 | |
status | tinyint | Y | 0-1 布尔类型值 0-false 1-true 启用还是禁用 |
created | datetime | Y | 创建时间 每张表里需要单独定义 可以进行封装优化 |
updated | datetime | Y | 修改时间 每张表里需要单独定义 可以进行封装优化 |
2. 用户登陆业务实现流程
-
步骤1: 用户输入完用户名和密码之后,点击登录按钮
-
步骤2: 准备username/password数据,向后台服务器发送请求,请求类型: post类型
-
步骤3: 后台服务器接收用户的请求参数 username/password
-
步骤4: 根据用户名和密码查询数据库
结果: 有数据 用户名和密码正确 | 没有结果 用户名和密码错误 -
步骤5: 后端服务器应该返回一个业务回执 标识业务逻辑是否正确执行
假设: status 200 正确, 201 表示失败 -
步骤6: 前端服务器根据用户的200/201 提示用户操作成功/操作失败.
3. 用户登录验证接口
说明:一般做前后端交互时,必须有业务接口文档。 文档中详细阐述了 业务需求 / url地址 /参数 / 返回值信息 等要素。
前后端严格按照业务接口文档进行编码。
请求
- 请求路径: /user/login
- 请求方式: POST
- 请求参数
参数名称 | 参数说明 | 备注 |
---|---|---|
username | 用户名 | 不能为空 |
password | 密码 | 不能为空 |
响应
- 响应数据 SysResult对象
参数名称 | 参数说明 | 备注 |
---|---|---|
status | 状态信息 | 200表示服务器请求成功 201表示服务器异常 |
msg | 服务器返回的提示信息 | 可以为null |
data | 服务器返回的业务数据 | 返回密钥token信息 |
返回值格式如下:
{"status":200,"msg":"服务器调用成功!","data":"1e893a97634847b3a8b499b173bea620"}
4.前端
登录界面
路径:src.components.Login.vue
<template>
<div class="login_container">
<div class="login_box">
<!-- 头像区域-->
<div class="avatar_box">
<img src="../assets/images/IU.png" alt="VUE图片" />
</div>
<!-- 登陆表单区域
ref代表当前表单引用对象
:model 是表格中封装的对象
-->
<el-form ref="loginFormRef" label-width="0" class="login_form" :model="loginForm" :rules="rules" >
<el-form-item prop="username">
<el-input prefix-icon="iconfont iconuser" v-model="loginForm.username"></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input prefix-icon="iconfont iconsuo" type="password" v-model="loginForm.password"></el-input>
</el-form-item>
<el-form-item class="btns">
<el-button type="primary" @click="login">登录</el-button>
<el-button type="info" @click="resetBtn">重置</el-button>
</el-form-item>
</el-form>
</div>
</div>
</template>
编辑login登录实现方法
路径:src.components.Login.vue
login(){
//获取表单对象之后进行数据校验
//valid 表示校验的结果 true表示通过 false表示失败
this.$refs.loginFormRef.validate(async valid => {
//如果没有完成校验则直接返回
if(!valid) return
//对输入框的数据进行封装,如果校验成功,则发起ajax请求 使用post类型
const {data: result} = await this.$http.post('/user/login',this.loginForm)
if(result.status !== 200) return this.$message.error("用户登录失败")
//登录信息响应提示框
this.$message.success("用户登陆成功")
//获取用户token信息
let token = result.data
//使用session的方式临时保存用户token信息
window.sessionStorage.setItem("token",token)
//用户登录成功之后,跳转到home页面
this.$router.push("/home")
})
}
编辑路由规则(页面跳转必配)
路径:src.router.index.vue
import Vue from 'vue'
import VueRouter from 'vue-router'
import Login from '../components/Login.vue'
import Home from '../components/Home.vue'
//使用路由机制 通过 children 实现路由嵌套, 通过 redirect 实现重定向
Vue.use(VueRouter)
const routes = [
{path: '/', redirect: '/login'},
{path: '/login', component: Login},
{path:'/home',component:Home}
]
//配置路由对象 先定义后使用
const router = new VueRouter({
//vue对象挂载路由 router: router
routes
})
token的作用
说明: 前端服务器: 用户进行登陆操作时 输入用户名和密码进行校验!!!
将数据信息发送到后端服务器进行校验,查询数据库。
假设: 用户用户名和密码正确!!! 页面应该跳转到系统的首页 “/home”
问题: 是否可以在浏览器中直接输入 “/home” 理论上不允许访问该页面!
解决方案:
后端服务器返回一个独一无二的 token数据, 前端只要携带token 认为该用户已经登陆。可以跳转页面.。权限操作雏形!!!
总结: token是用来标识用户已经登陆!!!
Session
Session: 在计算机中,尤其是在网络应用中,称为“会话控制”。Session对象存储特定用户会话所需的属性及配置信息。这样,当用户在应用程序的Web页之间跳转时,存储在Session对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。当用户请求来自应用程序的 Web页时,如果该用户还没有会话,则Web服务器将自动创建一个 Session对象。当会话过期或被放弃后,服务器将终止该会话。 Session 对象最常见的一个用法就是存储用户的首选项。例如,如果用户指明不喜欢查看图形,就可以将该信息存储在Session对象中。有关使用Session 对象的详细信息,请参阅“ASP应用程序”部分的“管理会话”。注意会话状态仅在支持cookie的浏览器中保留。
总结:
- Session 是会话控制
- Session可以用户存储数据
- Session生命周期整个会话 在会话期间数据有效, 如果会话窗口关闭则数据清除
- Session数据存储在浏览器的内存中(前端的)
Cookie(了解)
Cookie,有时也用其复数形式 Cookies。类型为“小型文本文件”,是某些网站为了辨别用户身份,进行Session跟踪而储存在用户本地终端上的数据(通常经过加密),由用户客户端计算机暂时或永久保存的信息 。
总结:
- Cookie 是一个文本文件
- Cookie 存储的是用户信息 (加密数据 更加安全)
- Cookie 保存到用户的计算机终端中 可以临时/永久的存储信息.
关于Session和Cookie的例子
手机银行的用户登录信息? session 安全性要求较高
购物网站 要求用户七天免密登录? 使用Cookie进行存储!!
公司的财务系统的登录信息? 建议使用Session
电影: 没有绝对安全的系统
总结: 如果对于数据安全性要求较高,则使用Session。 如果存储一些大量查询的数据(不重要的)一般采用Cookie进行保存。
路由守卫语法
路径:src.router.index.vue
业务说明
当用户没有登录时,不可以访问其他页面,如果sessionStorage中没有token数据,则表示没有登录。用该拦截,跳转到登录页面。
/* 配置路由导航守卫
当用户没有登录时,不可以访问其他页面 如果sessionStorage中没有token数据,则表示没有登录 用该拦截,跳转到登录页面
关于参数说明:
1. to 将要访问的路径
2. from 从哪个路径跳转来的
3. next 是一个函数 next() 表示放行 next("/login") 强制跳转*/
//router.beforeEach(function(parameter2,parameter2,parameter3){})
router.beforeEach((to,from,next) => {
//1.当用户访问登录页面,则直接放行 如果不需要执行后续操作 执行return(返回结果并终止程序)
if(to.path === '/login') return next()
//2.当用户访问其他页面 需要校验是否有token
let token = window.sessionStorage.getItem('token')
//如果数据为null 则访问登录页面
if(!token) return next('/login')
//如果数据不为null 则放行
next()
})
用户退出操作
业务说明
当用户点击退出按钮时,应该删除sessionStorage中的token信息. 并且访问登录页面
路径:src.components.Home.vue
logout() {
//1.删除session中的数据
window.sessionStorage.clear()
//2.用户访问登录页面
this.$router.push('/login')
}
5. 后端
创建BasePojo类
创建包: com.jt.pojo
创建类: BasePojo .java
//pojo基类,完成2个任务,2个日期,实现序列化
@Data
@Accessors(chain=true)
public class BasePojo implements Serializable{
@TableField(fill = FieldFill.INSERT)
private Date created; //表示入库时需要赋值
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updated; //表示入库/更新时赋值.
}
创建User类
创建包: com.jt.pojo
创建类: User.java
@Data //动态生成get/set方法
@TableName("user") //对象与表一一对应
@Accessors(chain = true) //链式加载结构
public class User extends BasePojo{
@TableId(type = IdType.AUTO)//ID主键自增
private Integer id;
private String username;
private String password;
private String phone;
private String email;
private Boolean status;
@TableField(exist = false) //该属性在表中不存在
private Role role; //定义role角色数据
}
创建SysResult类(系统返回值)
关于SysResult对象的说明: 该对象用来实现后端与前端业务的交互。
业务执行正确 status=200 业务执行错误 status=201
概念: 前后端交互的层级 定义为 VO层
创建包: com.jt.vo
创建类: SysResult .java
//作用: 实现前后端交互
@Data
@Accessors(chain = true)
@NoArgsConstructor //无参构造
@AllArgsConstructor //全参构造
public class SysResult implements Serializable { //规范的写法
private Integer status; //状态码 200 201
private String msg; //服务器返回的提示信息
private Object data; //服务器返回的业务数据
//重载: 方法名称相同,参数不同
//为了用户使用VO对象 更加的方便 重载一些方法 简化程序的调用
public static SysResult fail(){
return new SysResult(201, "业务执行失败",null);
}
//1.不带参数的正确返回
public static SysResult success(){
return new SysResult(200, "服务器处理成功", null);
}
//2.带返回值的正确返回 用户传递什么/返回值就是什么
public static SysResult success(Object data){
return new SysResult(200, "服务器处理成功", data);
}
//3.带返回值,携带提示信息
public static SysResult success(String msg,Object data){
return new SysResult(200, msg,data);
}
}
编辑UserController类
所属包: com.jt.controller
业务要求: 完成用户信息校验,并且返回特定的token数据
/**
* 业务需求:用户登陆校验
* 类型:POST
* URL: /user/login
* 参数: username/password json串 {username: "xxx", password: "xxx"}
* 返回值: SysResult对象 data的String类型的信息 token
* 用户名/密码 admin123/admin123456
*/
@PostMapping("/login")
public SysResult login(@RequestBody User user){
//1.根据用户名和密码校验 返回token Service层中完成
String token = userService.login(user);
//2. token 有值业务正确 | null 业务操作失败
if(token == null){
return SysResult.fail();
}
return SysResult.success(token);
}
编辑UserServiceImpl实现类
所属包: com.jt.sercvice
/**
* 需求:
* 1.根据用户名和密码查询数据库
* 2.将密码进行加密处理 md5加密方式
* 3.如果用户名和密码正确 返回token
* 4 UUID: 每次生成的UUID几乎不重复. 重复概率 2^128/1
* b809cd3e-f4fa-11eb-b396-52152e05da50
* @param user 作用: 在未来生成API文档时 有效果 一般都是默认的
* @return
*/
@Override
public String login(User user) {
//1.将密码进行加密的处理
String password = user.getPassword(); //明文
//2. 将字符串 转化为字节数组
byte[] passByte = password.getBytes();
//将明文加密
String md5Pass = DigestUtils.md5DigestAsHex(passByte);
//3. 根据用户名和密文查询数据库
//Sql: select * from user where uname="xxx" and ps="xx"
//根据对象中不为null的属性充当where条件!!!!
user.setPassword(md5Pass);
QueryWrapper<User> queryWrapper = new QueryWrapper<>(user);
//从数据库中获取结果
User userDB = userMapper.selectOne(queryWrapper);
if(userDB == null){ //用户名和密码错误 返回null
return null; //业务流程结束
}
//如果程序执行到这一行,则数据用户的输入正确的. 返回token
String token = UUID.randomUUID().toString().replace("-","");
return token;
}
MD5介绍
MD5信息摘要算法(英语:MD5 Message-Digest Algorithm),一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。MD5由美国密码学家罗纳德·李维斯特(Ronald Linn Rivest)设计,于1992年公开,用以取代MD4算法。这套算法的程序在 RFC 1321 标准中被加以规范。1996年后该算法被证实存在弱点,可以被加以破解,对于需要高度安全性的数据,专家一般建议改用其他算法,如SHA-2。2004年,证实MD5算法无法防止碰撞(collision),因此不适用于安全性认证,如SSL公开密钥认证或是数字签名等用途。
总结:
1.MD5信息摘要算法
2.通常可以将数据进行MD5加密 生成 “数字指纹”
3.现阶段md5的加密的算法应用于各大网站中
4.md5加密之后 理论上来说 无法由密文转化为明文 不可以反向编译
5. 限定输入密码的次数!!! 3-5次 锁定账户!!!
核心算法:
知识回顾: 高中的函数!!!
什么是函数: 给定未知数x 经过函数计算 得到一个唯一的结果y
实质: MD5的本质就是hash算法!!!
流传的MD5可以被破解的原理: 就是将md5进行反向查询
md5 改进版: hash(明文+ 盐值) 了解即可
更多推荐
所有评论(0)