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

做网站需要源码seo排名快速上升

做网站需要源码,seo排名快速上升,做课件赚钱网站,wordpress新建页面没有内容背景 我们在基于Session做登录认证的时候,会有一些问题,因为Session存储到服务器端,然后通过客户端的Cookie进行匹配,如果正确,则通过认证,否则不通过认证。这在简单的系统中可以这么使用,并且…

背景

我们在基于Session做登录认证的时候,会有一些问题,因为Session存储到服务器端,然后通过客户端的Cookie进行匹配,如果正确,则通过认证,否则不通过认证。这在简单的系统中可以这么使用,并且难度是最低的,但是如果在大型分布式项目中,如果还是基于Session做登录认证的话,就不可行了。这个时候我们可以基于token做登录认证。token其实就是一个字符串,生成token的实现方案有很多种,可以使用uuid作为token,也可以使用jwt作为token,其中使用jwt实现的方案是最流行的,那么下面将会讲如何在SpringBoot中基于jwt实现token登录认证。

1. 引入依赖

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

2. 自定义注解

自定义一个注解,在需要认证的方法上添加该注解

@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Auth {boolean require() default true;
}

3. 编写拦截器

通过识别是否在接口上添加@Auth注解来确定是否需要登录才能访问。

同时这里需要注意只拦截HandlerMethod类型,同时还要考虑放行BasicErrorController,因为基本的报错在这个控制器中,如果不放行,那么会看不到报错信息。

public class LoginInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {if (handler instanceof HandlerMethod) {HandlerMethod handlerMethod = (HandlerMethod) handler;if (handlerMethod.getBean() instanceof BasicErrorController) {return true;}Auth auth = handlerMethod.getMethod().getAnnotation(Auth.class);if (auth != null && auth.require()) {String token = request.getHeader("token");if (StringUtils.isNotBlank(token)) {if (TokenUtil.verifyToken(token)) { // 校验 token 是否正确return true;} else {request.getRequestDispatcher("/error/tokenError").forward(request, response); // 这里你也可以直接抛出自定义异常,然后在全局异常处理器中处理}} else {request.getRequestDispatcher("/error/token").forward(request, response); // 这里你也可以直接抛出自定义异常,然后在全局异常处理器中处理}} else {return true;}} else {return true;}return false;}
}

4. 定义跨域拦截器

这里是做前后端分离需要做的步骤,解决跨域的方式有好几种,这里使用拦截器的方式解决跨域问题。

public class CrossInterceptorHandler implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {response.setHeader("Access-Control-Allow-Origin", "*");response.setHeader("Access-Control-Allow-Credentials", "true");response.setHeader("Access-Control-Allow-Methods", "POST, GET , PUT , OPTIONS");response.setHeader("Access-Control-Max-Age", "3600");response.setHeader("Access-Control-Allow-Headers", "x-requested-with,accept,authorization,content-type");return true;}
}

5. 定义全局异常处理器

这里没有用到全局异常处理器,不过为了项目的完整性,我还是选择把这些常规的内容写上去。

@RestControllerAdvice
public class GlobalException {public final Logger logger = LoggerFactory.getLogger(this.getClass());@ExceptionHandler(TokenExpiredException.class)public R<?> handleTokenExpiredException(TokenExpiredException e) {logger.error("token 已过期");logger.error(e.getMessage());return R.error(ResponseEnum.TOKEN_EX);}
}

6. 定义工具类

6.1 统一错误状态码

编写一个枚举类,统一项目的报错状态码。

@AllArgsConstructor
@Getter
public enum ResponseEnum {SUCCESS(200, "操作成功"),FAIL(300,"获取数据失败"),USER_EX(301,"用户不存在,请重新登录"),ERROR(302,"错误请求"),USERNAME_PASSWORD_ERROR(303,"用户名或密码错误"),NO_TOKEN(400,"无token,请重新登录"),TOKEN_VERIFY_ERROR(401,"token验证失败,请重新登录"),TOKEN_EX(402,"token已过期");private final Integer code;private final String msg;public static ResponseEnum getResultCode(Integer code){for (ResponseEnum value : ResponseEnum.values()) {if (code.equals(value.getCode())){return value;}}return ResponseEnum.ERROR;}
}

6.2 统一响应类

@Data
public class R<T> implements Serializable {private static final long serialVersionUID = 56665257244236049L;private Integer code;private String message;private T data;private R() {}public static <T> R<T> ok(T data) {R<T> response = new R<>();response.setCode(ResponseEnum.SUCCESS.getCode());response.setMessage(ResponseEnum.SUCCESS.getMsg());response.setData(data);return response;}public static <T> R<T> error(Integer errCode, String errMessage) {R<T> response = new R<>();response.setCode(errCode);response.setMessage(errMessage);return response;}public static <T> R<T> error(ResponseEnum responseEnum) {R<T> response = new R<>();response.setCode(responseEnum.getCode());response.setMessage(responseEnum.getMsg());return response;}
}

6.3 Token工具类

通过TokenUtil可以生成token和验证token是否正确。

import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONObject;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;import java.util.Date;/*** @author Luke Ewin* @date 2024/2/19 16:59* @blog blog.lukeewin.top*/
public class TokenUtil {private final static String ENCRYPT_KEY = "abc123"; // 加密的密钥private final static int EXPIRE_TIME = 1; // token 过期时间,单位分钟private static final String ISSUER = "zhangsan";/*** 生成 token** @param json 要封装到 token 的内容,如果要传递多个参数内容,可以定义为 JSON 或者 Map* @return 返回 token*/public static String createToken(JSONObject json) {return JWT.create().withSubject(json.toString()) // 不要把密码封装进去,不安全.withIssuer(ISSUER) // 设置发布者.withExpiresAt(DateUtil.offsetMinute(new Date(), EXPIRE_TIME)) // 设置过期时间.withClaim("test", "123") // 这里是随便设置的内容,类似 Map.sign(Algorithm.HMAC256(ENCRYPT_KEY)); // 加密}/*** 验证 token** @param token* @return*/public static boolean verifyToken(String token) {try {JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(ENCRYPT_KEY)).withIssuer(ISSUER).build();jwtVerifier.verify(token);return true;} catch (Exception e) { // 如果 token 过期会报错 TokenExpiredExceptione.printStackTrace();return false;}}
}

7. 编写实体类

这里为了简单,并没有与数据库交互。

@Data
public class User {private String userName;private String password;private String token;
}

8. 定义控制器

8.1 定义登录控制器类

@RestController
@RequestMapping("/user")
public class LoginController {@PostMapping("/login")public R<User> login(String userName, String password) {if (StringUtils.isNotBlank(userName) && StringUtils.isNotBlank(password)) {if ("张三".equals(userName) && "123456".equals(password)) {User user = new User();JSONObject json = JSONUtil.createObj().put("name", "zhangsan");String token = TokenUtil.createToken(json);user.setToken(token);return R.ok(user);}}return R.error(ResponseEnum.USERNAME_PASSWORD_ERROR);}
}

8.2 定义报错处理器

@RestController
@RequestMapping("/error")
public class ErrorController {@PostMapping("/token")public R<?> token() {return R.error(ResponseEnum.NO_TOKEN);}@PostMapping("/tokenError")public R<?> tokenError() {return R.error(ResponseEnum.TOKEN_VERIFY_ERROR);}
}

8.3 定义测试控制器

@RestController
@RequestMapping("/test")
public class TestController {@Auth@PostMapping("/hello")public R<?> hello() {return R.ok("登录成功");}@PostMapping("/hi")public R<?> hi() {return R.ok("登录成功");}
}

9. 配置类

最后别忘了定义一个配置类,把我们自定义的两个拦截器注册进去。

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new CrossInterceptorHandler()).addPathPatterns(new String[] {"/**"});registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**").excludePathPatterns("/user/login", "/error/**");}
}

10. 最终的效果

访问登录接口,通过提交表单方式提交请求,通过token验证后会返回一个token,然后我们请求添加了@Auth注解的接口都需要在请求头添加token字段和对应的值。

image-20240220174407236

如果请求头中没有填写token或者填写的不对,在请求需求登录后才能访问的接口时都会报错。比如这里的/test/hello是需要登录后才能访问的接口,如果没有正确填写token,那么会报错,如下图所示。

image-20240220175045471 image-20240220174939307

如果正确填写了token,那么效果如下。

image-20240220175214721

有一个test/hi接口没有@Auth注解,可以不用登录就能访问,如下图所示。

image-20240220175428818

以上就是本篇文章所分享的内容,如果对你有用,记得收藏哦!

更多Java干货,欢迎关注我的博客。

代码已经开源到github中,如需要下载源代码,可点击这里。


文章转载自:
http://dinncoundisciplinable.tpps.cn
http://dinncotapu.tpps.cn
http://dinncoundersleep.tpps.cn
http://dinncogamekeeper.tpps.cn
http://dinncodelicate.tpps.cn
http://dinncoliberalization.tpps.cn
http://dinncodislocation.tpps.cn
http://dinncotyrtaeus.tpps.cn
http://dinncogigasecond.tpps.cn
http://dinncocentered.tpps.cn
http://dinncoasturias.tpps.cn
http://dinncopirogue.tpps.cn
http://dinnconutrition.tpps.cn
http://dinncolustrate.tpps.cn
http://dinncononviolent.tpps.cn
http://dinncoconglobulation.tpps.cn
http://dinncowoolenette.tpps.cn
http://dinncobarrable.tpps.cn
http://dinncoattainable.tpps.cn
http://dinncobiunique.tpps.cn
http://dinncouniparous.tpps.cn
http://dinncoistanbul.tpps.cn
http://dinncopennyroyal.tpps.cn
http://dinncozaftig.tpps.cn
http://dinncophytopathogen.tpps.cn
http://dinncopentachord.tpps.cn
http://dinncooverpaid.tpps.cn
http://dinncooccasion.tpps.cn
http://dinncotradable.tpps.cn
http://dinncoaltissimo.tpps.cn
http://dinncostitch.tpps.cn
http://dinncocirrous.tpps.cn
http://dinncoperch.tpps.cn
http://dinncowrb.tpps.cn
http://dinncophotoreconnaissance.tpps.cn
http://dinncocumulus.tpps.cn
http://dinncoonsweep.tpps.cn
http://dinncogruffly.tpps.cn
http://dinncoamboina.tpps.cn
http://dinncoradioactinium.tpps.cn
http://dinncodispositive.tpps.cn
http://dinncoalamode.tpps.cn
http://dinncoradius.tpps.cn
http://dinncotalocalcanean.tpps.cn
http://dinncomaneuverable.tpps.cn
http://dinncoampule.tpps.cn
http://dinncobedfast.tpps.cn
http://dinncogaunt.tpps.cn
http://dinncoinexactly.tpps.cn
http://dinncotierce.tpps.cn
http://dinncoanguifauna.tpps.cn
http://dinncophage.tpps.cn
http://dinncounbearably.tpps.cn
http://dinncomudcat.tpps.cn
http://dinncohereinbefore.tpps.cn
http://dinncoheteroplasia.tpps.cn
http://dinncoschizomycete.tpps.cn
http://dinncoidoneity.tpps.cn
http://dinncoparticipational.tpps.cn
http://dinncocapetonian.tpps.cn
http://dinncocarding.tpps.cn
http://dinncomonopolylogue.tpps.cn
http://dinncouxoriousness.tpps.cn
http://dinncoclownage.tpps.cn
http://dinncomusculoskeletal.tpps.cn
http://dinncoaccurate.tpps.cn
http://dinncodelian.tpps.cn
http://dinncomeekly.tpps.cn
http://dinncomeacock.tpps.cn
http://dinncomartemper.tpps.cn
http://dinncohomeomorphous.tpps.cn
http://dinncoshack.tpps.cn
http://dinncodiagonal.tpps.cn
http://dinncosciatic.tpps.cn
http://dinncowindmill.tpps.cn
http://dinncooutswing.tpps.cn
http://dinncokeyed.tpps.cn
http://dinncolifesome.tpps.cn
http://dinncofavoritism.tpps.cn
http://dinncoreadvance.tpps.cn
http://dinncodensity.tpps.cn
http://dinncobrandied.tpps.cn
http://dinncochilled.tpps.cn
http://dinncometoclopramide.tpps.cn
http://dinncotonite.tpps.cn
http://dinncobisync.tpps.cn
http://dinncochoreographer.tpps.cn
http://dinncodisme.tpps.cn
http://dinncoworthy.tpps.cn
http://dinncoscheduler.tpps.cn
http://dinncoswitzerland.tpps.cn
http://dinncodecagonal.tpps.cn
http://dinncokedge.tpps.cn
http://dinncounderemployed.tpps.cn
http://dinncommpi.tpps.cn
http://dinncoantidotal.tpps.cn
http://dinncoodontalgic.tpps.cn
http://dinncobiannually.tpps.cn
http://dinncobabyism.tpps.cn
http://dinncodecile.tpps.cn
http://www.dinnco.com/news/92171.html

相关文章:

  • 自适应网站会影响推广怎么做网络营销平台
  • 猛烈做瞹瞹视频澳洲网站win7优化大师官方免费下载
  • 宁波网站建设的步骤过程信息发布网站有哪些
  • 360做企业网站多少钱网络营销策略包括哪四种
  • 电脑在局域网做网站合肥网站推广公司
  • 日本设计师个人网站百度一下免费下载安装
  • 成都网站建设 培训p2p万能搜索种子
  • 免费制作头像的网站长沙seo结算
  • 帮做3d模型的网站中国营销策划第一人
  • 中国网站制作公司排名沈阳专业seo排名优化公司
  • 腾虎广州网站建设成都网络运营推广
  • 房产中介网站怎么做百度竞价推广账户
  • 国外简约网站如何做好推广引流
  • 餐饮 网站 模板百度快照推广有效果吗
  • wordpress的评论合肥网站建设优化
  • 触屏版网站开发百度自动点击器下载
  • 小说网站怎么做空间小输入搜索内容
  • 高效网站推广百度搜索app下载
  • lamp网站开发制作b2b网站
  • 家用电脑做网站广州seo顾问seocnm
  • 怎么强制下载网页视频seo工具网站
  • 中国建设银行网站首页手机银行百度网站推广一年多少钱
  • 我要啦免费统计怎么做网站百度网盘客服
  • 地方网站做相亲赢利点在哪里百度风云榜明星
  • 河东网站建设公司知名的建站公司
  • 快速创建一个网站谷歌平台推广外贸
  • 著名的响应式网站有哪些网站发布流程
  • 清新太和做网站网站搜索引擎优化方案
  • 襄阳市建设工程造价管理站网站电商运营一天都干啥
  • 网站各类备案南宁百度关键词推广