当前位置: 首页 > news >正文

做网站购买备案域名/新手电商运营从哪开始学

做网站购买备案域名,新手电商运营从哪开始学,美女色情做视频网站,建站空间目录 1. 为什么要用 JWT ? 认证 2.什么是 JWT 3. JWT 的结构 3.1 标头 3.2 载荷 3.3 签名 4. JWT 的认证流程 5. JWT 的使用 6. JWT 工具类 7. JWT 案例 7.1 用户登录 7.1.1 创建 SpringBoot 项目 7.1.2 引入依赖 7.1.3 application.yml 7.1.4 创建用户表 7.…

目录

1. 为什么要用 JWT ?

认证

2.什么是 JWT

3. JWT 的结构

3.1 标头

3.2 载荷

3.3 签名

4. JWT 的认证流程

5. JWT 的使用

6. JWT 工具类

7. JWT 案例

7.1 用户登录

7.1.1 创建 SpringBoot 项目

7.1.2 引入依赖

7.1.3 application.yml

7.1.4 创建用户表

7.1.5 用户实体类

7.1.6 Service 和实现类

7.1.7 Dao 和 mapper.xml

7.1.8 登录接口

7.1.9 测试

7.2 登录成功访问其他资源

7.2.1 创建拦截器

7.2.2 拦截器配置类

7.2.3 测试


Shiro安全框架【快速入门】及上手应用_是小晴晴呀的博客-CSDN博客

shiro 安全框架的讲解

1. 为什么要用 JWT ?

认证

在谈起 JWT 之前,我们先了解一下什么是认证

在登录淘宝、微博等软件或者网站之前,我们需要通过填写账号和密码来校验身份。认证是用来验证用户身份合法性的一种方式。

那我们登录成功之后,网站如何记录我们的身份信息呢?

前面我们在学习 servlet 的时候,知道了传统的系统主要是通过 session 来存储用户的信息。session 将用户的信息存储在服务端。

但是随着用户数量的增多,服务端就需要存一堆用户的认证信息,这种方式会不断增加服务端的压力。

如果是分布式系统,用 session 存储用户信息就太拘束了。因为分布式系统一般都会做负载均衡,如果这次认证成功了,那么意味着下次请求必须仍要访问这台服务器才能认证成功。

如果是前后端分离的系统就更难受了,因为前端代码和后端代码放在不同的服务器上,除了会增加服务器的压力,还会产生跨域等一系列问题,有点得不偿失。

那有没有一种工具能帮我们解决这些认证问题?

  1. 服务端不需要存储用户的认证信息
  2. 避免跨域
  3. 保证数据的安全性

JWT闪亮登场。

2.什么是 JWT

JWT 简称: JSON Web Token,又叫做 web 应用中的令牌。它可以帮助我们完成用户的认证、存储信息、加密数据等功能。

那什么是令牌呢?令牌就相当于古代的虎符。

古代将军要想调兵遣将,必须手持虎符。

而用户要想访问系统中的某些页面,在发起的请求中必须携带使用 JWT 生成的令牌。令牌校验通过了,方可访问系统。这里的令牌简称为 token

3. JWT 的结构

注:这里所说的 JWT 的结构,指的是用 JWT 生成令牌的结构,也就是 token 的结构。

令牌的结构组成:

    1. 标头(Header)
    1. 载荷(Payload)
    1. 签名(Signature)

令牌最终的样子是由这三部分组成的字符串:

Header.Payload.Signature

例如:

hjYGH1dajUU.dajhjksfiu2h27jjghg2.kjbhjkf982bhh2lk2

3.1 标头

标头是使用 Base64 编码将令牌类型签名算法经过加工后生成的一段字符串

标头包含两部分:

  • 令牌的类型:JWT(一般是默认的)
  • 签名算法:例如 SHA256、HMAC等
{"alg": "HS256","typ": "JWT"
}

3.2 载荷

载荷主要存储一些自定义信息。它也是使用 Base64 编码加工后生成的一段字符串。

3.3 签名

签名是通过一个秘钥和标头中提供的算法再将标头和载荷进行加工后生成的一段字符串。例如:

4. JWT 的认证流程

  1. 用户点击登录,后台接收用户请求并根据账号和密码从数据库查询用户信息。用户若存在,则使用 JWT 生成 token 并返回给前台。用户若不存在,则返回错误信息。
  2. 前端在请求其他资源时将 token 放到请求头中。
  3. 后台从请求头中获取 token 信息,如果 token 校验失败,则返回错误信息。如果校验成功,就将业务数据返回给前端。

5. JWT 的使用

1.引入依赖

<dependency><groupId>com.auth0</groupId><artifactId>java-jwt</artifactId><version>3.10.3</version>
</dependency>

2.生成token

public static void main(String[] args) {Date date = new Date(System.currentTimeMillis() +1000);Algorithm algorithm = Algorithm.HMAC256("!Secret");String token =  JWT.create().withClaim("name", "张三").withExpiresAt(date) // 设置过期时间.sign(algorithm);     // 设置签名算法System.out.println(token);
}

生成结果:

"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.
eyJuYW1lIjoi5byg5LiJIiwiZXhwIjoxNjUwNzE1OTg3fQ.
-hrxN6RwXCPnI-pmQaIsetx-8iN98XwZczmTFBoV1FI"
  1. 校验 token

校验 token,其实就是比较 token 是否真确,如果不正确程序就会报错。

String token = "";
JWT.require(Algorithm.HMAC256("!Secret")).build().verify(token);
  1. 获取 token 中的载荷信息
String token=" ";
DecodedJWT jwt = JWT.decode(token);
String name =  jwt.getClaim("name").asString();
  1. 判断 token 是否过期
public boolean isExpire(String token) {DecodedJWT jwt = JWT.decode(token);// 如果token的过期时间小于当前时间,则表示已过期,为truereturn jwt.getExpiresAt().getTime() < System.currentTimeMillis();}

6. JWT 工具类

因为 JWT 的作用主要是生成 token、校验 token、获取token中存储的自定义信息,所以我们一般会把 JWT 封装成一个工具类。

public class JwtUtil {// 秘钥private static final String SECRET = "SECRET_PRIVATE!";private static final long TIME_UNIT = 1000;// 生成包含用户id的tokenpublic static String createJwtToken(String userId, long expireTime) {Date date = new Date(System.currentTimeMillis() + expireTime * TIME_UNIT);Algorithm algorithm = Algorithm.HMAC256(SECRET);return JWT.create().withClaim("userId", userId).withExpiresAt(date) // 设置过期时间.sign(algorithm);     // 设置签名算法}// 生成包含自定义信息的tokenpublic static String createJwtToken(Map<String, String> map, long expireTime) {JWTCreator.Builder builder = JWT.create();if (MapUtil.isNotEmpty(map)) {map.forEach((k, v) -> {builder.withClaim(k, v);});}Date date = new Date(System.currentTimeMillis() + expireTime * TIME_UNIT);Algorithm algorithm = Algorithm.HMAC256(SECRET);return builder.withExpiresAt(date) // 设置过期时间.sign(algorithm);     // 设置签名算法}// 校验token,其实就是比较tokenpublic static DecodedJWT verifyToken(String token) {// 如果校验失败,程序会抛出异常return JWT.require(Algorithm.HMAC256(SECRET)).build().verify(token);}// 从token中获取用户idpublic static String getUserId(String token) {try {DecodedJWT jwt = JWT.decode(token);return jwt.getClaim("userId").asString();} catch (JWTDecodeException e) {return null;}}// 从token中获取定义的荷载信息public static String getTokenClaim(String token, String key) {try {DecodedJWT jwt = JWT.decode(token);return jwt.getClaim(key).asString();} catch (JWTDecodeException e) {return null;}}// 判断 token 是否过期public static boolean isExpire(String token) {DecodedJWT jwt = JWT.decode(token);// 如果token的过期时间小于当前时间,则表示已过期,为truereturn jwt.getExpiresAt().getTime() < System.currentTimeMillis();}
}

7. JWT 案例

这里我们通过一个 springboot 项目来感受一下 JWT 的使用过程。

  • 开发工具:IDEA
  • 技术栈:SpringBoot、MyBatisPlus、JWT
  • 数据库:Mysql

7.1 用户登录

7.1.1 创建 SpringBoot 项目

7.1.2 引入依赖

 <!--web-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency><!--myql-->
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope>
</dependency><!--lombok-->
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional>
</dependency><!--mybatis plus-->
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.0</version>
</dependency><!--引入jwt-->
<dependency><groupId>com.auth0</groupId><artifactId>java-jwt</artifactId><version>3.10.3</version>
</dependency><!--hutool-->
<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.5.7</version>
</dependency><!--test-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope>
</dependency>

7.1.3 application.yml

server:port: 8082servlet:context-path: /jwt-demo
spring:# 数据源datasource:url: jdbc:mysql://localhost:3306/jwt_demo?allowPublicKeyRetrieval=true&useSSL=falseusername: rootpassword: 12345678driver-class-name: com.mysql.cj.jdbc.Driver
# MybatisPlus
mybatis-plus:global-config:db-config:field-strategy: IGNOREDcolumn-underline: truelogic-delete-field: isDeleted # 全局逻辑删除的实体字段名logic-delete-value: 1 # 逻辑已删除值(默认为 1)logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)db-type: mysqlid-type: assign_idmapper-locations: classpath*:/mapper/**Mapper.xmltype-aliases-package: com.zhifou.entityconfiguration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #日志

7.1.4 创建用户表

CREATE TABLE `t_user` (`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',`username` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '姓名',`password` varchar(20) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '密码',PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=39 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;

7.1.5 用户实体类

@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@TableName("t_user")
public class User implements Serializable {private static final long serialVersionUID = 1L;/*** id*/@TableId(value = "id", type = IdType.ASSIGN_ID)private Long id;/*** 姓名*/private String username;/*** 密码*/private String password;
}

7.1.6 Service 和实现类

UserService

public interface UserService extends IService<User> {/*** 登录* @param user* @return*/User login(User user);
}
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {@Overridepublic User login(User user) {User userOne = this.getOne(new QueryWrapper<User>().eq("username", user.getUsername()).eq("password", user.getPassword()));return null == userOne ? null : userOne;}
}

7.1.7 Dao 和 mapper.xml

UserMapper

public interface UserMapper extends BaseMapper<User> {}

UserMapper.xml

<?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.zhifou.mapper.UserMapper"><!-- 通用查询映射结果 --><resultMap id="BaseResultMap" type="com.zhifou.entity.User"><id column="id" property="id" /><result column="username" property="username" /><result column="password" property="password" /></resultMap><!-- 通用查询结果列 --><sql id="Base_Column_List">id, username, password, sex, age</sql></mapper>

7.1.8 登录接口

@PostMapping("/login")
public Map<String, Object> login(@RequestBody User user) {Map<String, Object> data = new HashMap<>();User userOne = userService.login(user);if (null != userOne) {data.put("code", 200);data.put("msg", "登陆成功");data.put("token", JwtUtil.createJwtToken(userOne.getId().toString(), 24 * 10));} else {data.put("code", 400);data.put("msg", "账号或者密码错误");}return data;
}

7.1.9 测试

登录成功

登录失败

7.2 登录成功访问其他资源

用户登录成功后,我们把 token 返回给了前端。用户再次访问该网站的其他资源,我们怎么判断当前的用户和上次登录成功后的用户是同一个用户呢?

只需要两步:

    1. 前端:请求头中携带 token
    1. 后端:配置拦截器,校验 token

7.2.1 创建拦截器

MyInterceptor

/*** @Desc:* @Author: * @date: 下午7:11 2022/4/24*/
public class MyInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String token = request.getHeader("token");Map<String, Object> result = new HashMap<>();try {// 校验token,校验失败会抛出异常JwtUtil.verifyToken(token);return true;} catch (TokenExpiredException e) {e.printStackTrace();result.put("code", "500");result.put("msg", "token已过期");} catch (Exception e) {e.printStackTrace();result.put("code", "500");result.put("msg", "token无效");}response.setContentType("application/json;charset=UTF-8");response.getWriter().println(JSONUtil.parse(result));return false;}
}

7.2.2 拦截器配置类

/*** @Desc:* @Author: 知否技术* @date: 下午7:18 2022/4/24*/
@Component
public class InterceptorConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new MyInterceptor())// 拦截所有请求.addPathPatterns("/**")// 排除路径,比如用户登录、退出等.excludePathPatterns("/user/login");}
}

7.2.3 测试

token 校验失败

token 校验成功

http://www.jmfq.cn/news/4876777.html

相关文章:

  • 365做网站/医院网络销售要做什么
  • 现在用什么工具建网站/百度分析
  • 唐山网站建设电话/外贸全网营销推广
  • 网站设计培训学校有哪些/免费seo优化
  • 货车保险哪家网站可以直接做/用模板快速建站
  • 常州网站建设公司/近期国内新闻
  • 犀牛云做网站一年多少钱/网络营销服务公司有哪些
  • 网站开发河南/seo基础优化包括哪些内容
  • 爱淘宝网页网站建设/网站不收录怎么办
  • 成交型网站/怎么在百度上做公司网页
  • 怎么建设外贸网站/发帖百度秒收录网站分享
  • 注册网站怎么做网站/百度品牌推广
  • 做家居建材出口网站有哪些/平面设计网站
  • 怎么建设一个网站/网站seo报价
  • 北京学校网站建设公司/深圳网站关键词优化推广
  • 江苏建设考试培训网/seo推广教程
  • 上海做网络推广/大连网站seo
  • pc做任务赚钱的网站/新网站推广最直接的方法
  • 建设网站能解决什么问题/外包接单平台
  • 网站如何做抖音推广/公司推广文案
  • web需要学什么内容/百度seo排名优化
  • 买公司的网站/北京seo排名外包
  • wordpress做的好的网站/广东培训seo
  • 网站开发项目实战视频/青岛建站seo公司
  • 商务酒店网站建设/最新百度关键词排名
  • 给别人做网站/百度灰色关键词排名代做
  • 网站开发外包 价格/郑州网站策划
  • 做网站在线支付系统多少钱/制作网站费用
  • 重庆网站建设推广/网易疫情实时最新数据
  • 在线音乐网站开发php/亚马逊关键词工具哪个最准