何为token?【如果想直接看代码可以往下翻】

使用基于 Token 的身份验证方法,在服务端不需要存储用户的登录记录。大概的流程是这样的:
1. 客户端使用用户名跟密码请求登录
2. 服务端收到请求,去验证用户名与密码
3. 验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端
4. 客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里
5. 客户端每次向服务端请求资源的时候需要带着服务端签发的 Token
6. 服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据

token优点

支持跨域访问: Cookie是不允许垮域访问的,这一点对Token机制是不存在的,前提是传输的用户认证信息通
过HTTP头传输.
无状态(也称:服务端可扩展行):Token机制在服务端不需要存储session信息,因为Token 自身包含了所有登
录用户的信息,只需要在客户端的cookie或本地介质存储状态信息.
更适用CDN: 可以通过内容分发网络请求你服务端的所有资料(如:javascript,HTML,图片等),而你的服
务端只要提供API即可.
去耦: 不需要绑定到一个特定的身份验证方案。Token可以在任何地方生成,只要在你的API被调用的时候,你
可以进行Token生成调用即可.
更适用于移动应用: 当你的客户端是一个原生平台(iOS, Android,Windows 8等)时,Cookie是不被支持的
(你需要通过Cookie容器进行处理),这时采用Token认证机制就会简单得多。
CSRF:因为不再依赖于Cookie,所以你就不需要考虑对CSRF(跨站请求伪造)的防范。
性能: 一次网络往返时间(通过数据库查询session信息)总比做一次HMACSHA256计算 的Token验证和解析
要费时得多.
不需要为登录页面做特殊处理: 如果你使用Protractor 做功能测试的时候,不再需要为登录页面做特殊处理.
基于标准化:你的API可以采用标准化的 JSON Web Token (JWT). 这个标准已经存在多个后端库(.NET, Ruby,
Java,Python, PHP)和多家公司的支持(如:Firebase,Google, Microsoft)

如何创建token【我这里用的是Jwt机制,有些公司用的是自己的生成方法哈】

(1)创建maven工程,引入依赖

<dependency>
   <groupId>io.jsonwebtoken</groupId>
   <artifactId>jjwt</artifactId>
   <version>0.6.0</version>
</dependency>

(2)使用工具类JwtUtils

 /**
* @author: Mr.Yang
* @create: 2020-02-13 21:19
**/
@Getter
@Setter
@ConfigurationProperties("jwt.config")
public class JwtUtils {
//签名私钥
private String key;
//签名失效时间
private Long failureTime; /**
* 设置认证token
*
* @param id 用户登录ID
* @param subject 用户登录名
* @param map 其他私有数据
* @return
*/
public String createJwt(String id, String subject, Map<String, Object> map) { //1、设置失效时间啊
long now = System.currentTimeMillis(); //毫秒
long exp = now + failureTime; //2、创建JwtBuilder
JwtBuilder jwtBuilder = Jwts.builder().setId(id).setSubject(subject)
.setIssuedAt(new Date())
//设置签名防止篡改
.signWith(SignatureAlgorithm.HS256, key); //3、根据map设置claims
for (Map.Entry<String, Object> entry : map.entrySet()) {
jwtBuilder.claim(entry.getKey(), entry.getValue());
}
jwtBuilder.setExpiration(new Date(exp)); //4、创建token
String token = jwtBuilder.compact();
return token;
} /**
* 解析token
*
* @param token
* @return
*/
public Claims parseJwt(String token) {
Claims claims = Jwts.parser().setSigningKey(key).parseClaimsJws(token).getBody();
return claims;
} }

注意:

@ConfigurationProperties("jwt.config")需要在配置文件中配置

(3)配置JwtUtils类
     /**
* 配置jwt
*
* @return
*/
@Bean
public JwtUtils jwtUtils() {
return new JwtUtils();
}

(4)编写登录方法

  1、编写DAO层

 /**
* @author: Mr.Yang
* @create: 2020-02-13 21:55
**/
@Repository
public interface UserDAO { public User selectByMobileUser(String mobile); public User selectByIdUser(String id);
}

  2、编写xml写Sql

 <select id="selectByMobileUser" parameterType="string" resultMap="userMap">
select *
from bs_user
where mobile = #{mobile}
</select>

  3、编写service层

 /**
* 根据mobile查询用户
*
* @param mobile
* @return
*/
public User selectByMobile(String mobile) {
return userDAO.selectByMobileUser(mobile);
}

  4、编写controller层

  /**
* 用户登录
* 1.通过service根据mobile查询用户
* 2.比较password
* 3.生成jwt信息
*
* @param loginMap
* @return
* @requestBody把请求数据封装(前端以json方式传)
*/
@RequestMapping(value = "/login", method = RequestMethod.POST)
public Result login(@RequestBody Map<String, String> loginMap) {
String mobile = loginMap.get("mobile");
String password = loginMap.get("password");
User user = userService.selectByMobile(mobile);
//登录失败
if (user == null || !user.getPassword().equals(password)) {
//既可以使用抛异常,也可使用直接返回错误码(推荐)
return new Result(ResultCode.MOBILEORPASSWORDERROR);
} else {
//其他数据以map集合存放在token中
Map<String, Object> dataMap = new HashMap<>();
dataMap.put("companyId", user.getCompanyId());
dataMap.put("companyName", user.getCompanyName());
//生成token并存入数据返回
String token = jwtUtils.createJwt(user.getId(), user.getUsername(), dataMap);
return new Result(Result.SUCCESS(), token);
}
}

  5、测试

data就是返回的token,里面存有用户ID,用户姓名及以map形式存入的数据(这里主要看前端需要什么就存什么)


(6)用户登录成功之后,获取用户信息

  /**
* 用户登录成功之后,获取用户信息
* 1.获取用户id
* 2.根据用户id查询用户
* 3.构建返回值对象
* 4.响应
*
* @param request
* @return
* @throws Exception
*/
@RequestMapping(value = "/profile", method = RequestMethod.POST)
public Result profile(HttpServletRequest request) throws PendingException, Exception { /**
* 从请求头信息中获取token数据
* 1.获取请求头信息:名称=Authorization(前后端约定)
* 2.替换Bearer+空格
* 3.解析token
* 4.获取clamis
*/ //1.获取请求头信息:名称=Authorization(前后端约定)
String authorization = request.getHeader("Authorization");
if (StringUtils.isEmpty(authorization)) {
// throw new PendingException(ResCode.UNAUTHENTICATED);
//系统未捕捉到请求头信息
throw new CommonException(ResultCode.UNAUTHENTICATED);
}
//2.替换Bearer+空格
String token = authorization.replace("Bearer ", ""); //3.解析token
Claims claims = jwtUtils.parseJwt(token);
//4.获取clamis
String userId = claims.getId(); // String userId = "U01";
User user = userService.selectByIdUser(userId); /**此处只是为了获取token中的用户数据,所有只简单返回用户对象,
* 工作则按实际要求多表查询需要数据(根据用户ID查询权限)
*/ return new Result(ResultCode.SUCCESS, user);
}

(7)测试

用户登录并返回token(springboot)的更多相关文章

  1. 后台获取用户登录token 和获取前端参数方法

    //获取request请求中所有参数 Enumeration<String> names = request.getParameterNames(); HashMap<String, ...

  2. day102:MoFang:后端完成对短信验证码的校验&基于celery完成异步短信发送&flask_jwt_extended&用户登录的API接口

    目录 1.用户注册 1.后端完成对短信验证码的校验 2.基于celery实现短信异步发送 2.用户登录 1.jwt登录验证:flask_jwt_extended 2.服务端提供用户登录的API接口 1 ...

  3. 利用MYSQL的函数实现用户登录功能,进出都是JSON(第二版)

    利用MYSQL的函数实现用户登录功能,进出都是JSON(第二版) CREATE DEFINER=`root`@`%` FUNCTION `uc_session_login`( `reqjson` JS ...

  4. MYSQL存储过程实现用户登录

    MYSQL存储过程实现用户登录 CREATE DEFINER=`root`@`%` PROCEDURE `uc_session_login`( ), ) ) LANGUAGE SQL NOT DETE ...

  5. .Net Core 实现账户充值,还款,用户登录(WebApi的安全)

    个人未开通网站: http://justin1107.pc.evyundata.cn/vip_justin1107.html Api using System; using System.Collec ...

  6. [springboot 开发单体web shop] 5. 用户登录及首页展示

    用户登录及前端展示 用户登录 在之前的文章中我们实现了用户注册和验证功能,接下来我们继续实现它的登录,以及登录成功之后要在页面上显示的信息. 接下来,我们来编写代码. 实现service 在com.l ...

  7. vue 根据接口返回的状态码判断用户登录状态并跳转登录页,登录后回到上一个页面(http拦截器)

    背景:后台接口返回code==501表示用户是未登录状态,需要登录才可访问: 通过http拦截做路由跳转 第一步:src目录下新建http.js文件,内容如下: import Axios from ' ...

  8. Springboot - 建立简单的用户登录系统

    在开始编码前,先建立几个Package(可以按个人习惯命名),如图 1.Controllers 用于存放控制器类 2.Models 用于存放数据实体类 3.Repositories 用于存放数据库操作 ...

  9. 小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_5-10.Springboot2.x用户登录拦截器开发实战

    笔记 10.Springboot2.x用户登录拦截器开发实战     简介:实战开发用户登录拦截器拦截器 LoginInterceptor                  1.实现接口 LoginI ...

随机推荐

  1. CTPN中anchors代码

    import numpy as np def generate_basic_anchors(sizes, base_size=16): #base_anchor([0,0,15,15]) base_a ...

  2. CF825G Tree Queries

    [题意] 一棵树有 n个节点,初始均为白色,有两种操作: 1. 1 x 代表把结点 x 设置为黑色 2. 2 x 代表查询 x 到树上任意一个黑色结点的简单路径上的编号最小的结点的编号 输入 t 和 ...

  3. Scala与Mongodb实践4-----数据库操具体应用

    目的:在实践3中搭建了运算环境,这里学会如何使用该环境进行具体的运算和相关的排序组合等. 由数据库mongodb操作如find,aggregate等可知它们的返回类型是FindObservable.A ...

  4. 2018 CCPC 网络赛

    The Power Cube is used as a stash of Exotic Power. There are n cities numbered 1,2,…,n where allowed ...

  5. 构造分组背包(CF)

    Ivan is a student at Berland State University (BSU). There are n days in Berland week, and each of t ...

  6. ASP.NET 开源导入导出库Magicodes.IE 导出Pdf教程

    基础教程之导出Pdf收据 说明 本教程主要说明如何使用Magicodes.IE.Pdf完成Pdf收据导出 要点 导出PDF数据 自定义PDF模板 导出单据 如何批量导出单据 导出特性 PdfExpor ...

  7. 【VBA】EXCEL通过VBA生成SQL,自动生成创建表结构SQL

    原文:https://blog.csdn.net/zutsoft/article/details/45441343 编程往往与数据库密不可分,一个项目往往有很多的表,很多时候通过excel来维护表结构 ...

  8. 《Sequence Models》课堂笔记

    Lesson 5 Sequence Models 这篇文章其实是 Coursera 上吴恩达老师的深度学习专业课程的第五门课程的课程笔记. 参考了其他人的笔记继续归纳的. 符号定义 假如我们想要建立一 ...

  9. Python的条件控制及循环

    一.条件控制: 1.If语句的使用: Python中if语句的一般形式如下所示: 上图中: 如果 "score>=90" 为 True 将执行 "print(‘优秀 ...

  10. gulp实现自动化打包(二)

    引言 在这篇文章中我基于上一篇文章gulp的简单打包示例(一)的代码(重点,不然看的懵逼状态)来介绍gulp的自动化打包,主要是修改gulpfile.js配置文件.当我们执行gulp任务,gulp自动 ...