springboot第25集:实体类定义规则
PO:持久化对象,一个PO对象对应一张表里面的一条记录。全部对应
VO:View视图对象,用来在页面中展示数据的,页面需要哪些字段属性就添加哪些,查询出来之后赋值操作比PO对象要简单。所以提高性能。
DTO:数据传递对象,如果要查询的结果集有多张表,或者从多个表获得的数据就可以封装DTO对象,把这些表的数据全部封装到一起,形成一个对象。
POJO:中间形态,可以在PO,VO,DTO之间互相转换。
POJO在保存数据,PO
POJO在表示层,VO
POJO数据传递,DTO
package com.xxx.app.controller;import java.util.List;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.xxx.common.core.domain.AjaxResult;
import com.xxx.common.core.domain.entity.SysMenu;
import com.xxx.common.core.domain.entity.SysUser;
import com.xxx.common.core.domain.model.LoginBody;
import com.xxx.common.utils.SecurityUtils;
import com.xxx.framework.web.service.SysLoginService;
import com.xxx.framework.web.service.SysPermissionService;
import com.xxx.system.service.ISysMenuService;/*** 登录验证**/
@RestController
public class SysLoginController
{@Autowiredprivate SysLoginService loginService;@Autowiredprivate ISysMenuService menuService;@Autowiredprivate SysPermissionService permissionService;/*** 登录方法** @param loginBody 登录信息* @return 结果*/@PostMapping("/login")public AjaxResult login(@RequestBody LoginBody loginBody){AjaxResult ajax = AjaxResult.success();// 生成令牌
// String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
// loginBody.getUuid());
// ajax.put(Constants.TOKEN, token);return ajax;}/*** 获取用户信息** @return 用户信息*/@GetMapping("getInfo")public AjaxResult getInfo(){SysUser user = SecurityUtils.getLoginUser().getUser();// 角色集合Set<String> roles = permissionService.getRolePermission(user);// 权限集合Set<String> permissions = permissionService.getMenuPermission(user);AjaxResult ajax = AjaxResult.success();ajax.put("user", user);ajax.put("roles", roles);ajax.put("permissions", permissions);return ajax;}/*** 获取路由信息** @return 路由信息*/@GetMapping("getRouters")public AjaxResult getRouters(){Long userId = SecurityUtils.getUserId();List<SysMenu> menus = menuService.selectMenuTreeByUserId(userId);return AjaxResult.success(menuService.buildMenus(menus));}
}
// AjaxResult ajax = AjaxResult.success();
// String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
// loginBody.getUuid());
// ajax.put(Constants.TOKEN, token);
// return ajax;
一般流程是下面这样。
1、用户向服务器发送用户名和密码。
2、服务器验证通过后,在当前对话(session)里面保存相关数据,比如用户角色、登录时间等等。
3、服务器向用户返回一个 session_id,写入用户的 Cookie。
4、用户随后的每一次请求,都会通过 Cookie,将 session_id 传回服务器。
5、服务器收到 session_id,找到前期保存的数据,由此得知用户的身份。
http://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html
JWT 作为一个令牌(token),有些场合可能会放到 URL(比如 api.example.com/?token=xxx)。Base64 有三个字符+
、/
和=
,在 URL 里面有特殊含义,所以要被替换掉:=
被省略、+
替换成-
,/
替换成_
。这就是 Base64URL 算法。
客户端收到服务器返回的 JWT,可以储存在 Cookie 里面,也可以储存在 localStorage。
此后,客户端每次与服务器通信,都要带上这个 JWT。你可以把它放在 Cookie 里面自动发送,但是这样不能跨域,所以更好的做法是放在 HTTP 请求的头信息Authorization
字段里面。
private String createToken(Map<String, Object> claims) {String token = Jwts.builder().setClaims(claims).signWith(SignatureAlgorithm.HS512,secret).compact();return token;
}


public String createToken(LoginUser loginUser)
{String token = IdUtils.fastUUID();loginUser.setToken(token);setUserAgent(loginUser);refreshToken(loginUser);Map<String, Object> claims = new HashMap<>();claims.put(Constants.LOGIN_USER_KEY, token);return createToken(claims);
}
tokenService.getLoginUser(request);
Claims claims = parseToken(token);
private Claims parseToken(String token)
{return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
}
private String getToken(HttpServletRequest request)
{String token = request.getHeader(header);if (StringUtils.isNotEmpty(token) && token.startsWith(Constants.TOKEN_PREFIX)){token = token.replace(Constants.TOKEN_PREFIX, "");}return token;
}

const whiteList = [];
router.beforeEach((to, from, next) => {NProgress.start()if (getToken
})
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
添加一个配置类,配置拦截的路径
@Configuration
public class SecurityConfig extends WebSecurityConfigureAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.formLogin() // 表单登录.add().authorizeRequests() // 认证配置.anyRequest() // 任何请求.authenticated(); // 需要身份验证}
}
编写一个简单的controller测试
@RequestMapping("hello")
@RestController
public class HelloController {@GetMapping("test")public String test() {return "spring security";}
}

(1)JWT 默认是不加密,但也是可以加密的。生成原始 Token 以后,可以用密钥再加密一次。
(2)JWT 不加密的情况下,不能将秘密数据写入 JWT。
(3)JWT 不仅可以用于认证,也可以用于交换信息。有效使用 JWT,可以降低服务器查询数据库的次数。
(4)JWT 的最大缺点是,由于服务器不保存 session 状态,因此无法在使用过程中废止某个 token,或者更改 token 的权限。也就是说,一旦 JWT 签发了,在到期之前就会始终有效,除非服务器部署额外的逻辑。
(5)JWT 本身包含了认证信息,一旦泄露,任何人都可以获得该令牌的所有权限。为了减少盗用,JWT 的有效期应该设置得比较短。对于一些比较重要的权限,使用时应该再次对用户进行认证。
(6)为了减少盗用,JWT 不应该使用 HTTP 协议明码传输,要使用 HTTPS 协议传输。
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter
{@Bean@Overrideprotected AuthenticationManager authenticationManager() throws Exception {return super.authenticationManager();}
}Authentication authentication = SecurityContextHolder.getContext().getAuthentication()
/*** 获取Authentication*/
public static Authentication getAuthentication()
{return SecurityContextHolder.getContext().getAuthentication();
}
Authentication: 存储了认证信息,代表当前登录用户
SeucirtyContext: 上下文对象,用来获取Authentication
SecurityContextHolder: 上下文管理对象,用来在程序任何地方获取SecurityContext
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception
{return super.authenticationManagerBean();
}
@RestController
@RequestMapping("/API")
public class LoginController {@Autowiredprivate AuthenticationManager authenticationManager;@PostMapping("/login")public String login(@RequestBody LoginParam param) {// 生成一个包含账号密码的认证信息Authentication token = new UsernamePasswordAuthenticationToken(param.getUsername(), param.getPassword());// AuthenticationManager校验这个认证信息,返回一个已认证的AuthenticationAuthentication authentication = authenticationManager.authenticate(token);// 将返回的Authentication存到上下文中SecurityContextHolder.getContext().setAuthentication(authentication);return "登录成功";}
}
@Autowired
private PasswordEncoder passwordEncoder;@PostMapping("/register")
public String register(@RequestBody UserParam param) {UserEntity user = new UserEntity();// 调用加密器将前端传递过来的密码进行加密user.setUsername(param.getUsername()).setPassword(passwordEncoder.encode(param.getPassword()));// 将用户实体对象添加到数据库userService.save(user);return "注册成功";
}
认证管理器,调用,认证方法

try
{UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);AuthenticationContextHolder.setContext(authenticationToken);// 该方法会去调用UserDetailsServiceImpl.loadUserByUsernameauthentication = authenticationManager.authenticate(authenticationToken);
}
@Service
public class UserDetailsServiceImpl implements UserDetailsService
{
}
@Resource
private AuthenticationManager authenticationManager;
调用这个认证方法
authenticate
SysUser user = userService.selectUserByUserName(username);
通过用户名查询用户

/*** 强散列哈希加密实现*/
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder()
{return new BCryptPasswordEncoder();
}/*** 身份认证接口*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception
{auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
}

loadUserByUsername
SysUser user = userService.selectUserByUserName(username);
@Override
public SysUser selectUserByUserName(String userName)
{return userMapper.selectUserByUserName(userName);
}
public SysUser selectUserByUserName(String userName);

public class LoginUser implements UserDetails
{
}
{this.userId = userId;this.deptId = deptId;this.user = user;this.permissions = permissions;
}
public UserDetails createLoginUser(SysUser user)
{return new LoginUser(user.getUserId(), user.getDeptId(), user, permissionService.getMenuPermission(user));
}
public LoginUser(Long userId, Long deptId, SysUser user, Set<String> permissions)
{this.userId = userId;this.deptId = deptId;this.user = user;this.permissions = permissions;
}@JSONField(serialize = false)
@Override
public String getPassword()
{return user.getPassword();
}


private ScheduledExecutorService executor = SpringUtils.getBean("scheduledExecutorService");
LoginUser loginUser = (LoginUser) authentication.getPrincipal();
recordLoginInfo(loginUser.getUserId());
// 生成token
return tokenService.createToken(loginUser);
/*** 设置用户代理信息** @param loginUser 登录信息*/
public void setUserAgent(LoginUser loginUser)
{UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent"));String ip = IpUtils.getIpAddr();loginUser.setIpaddr(ip);loginUser.setLoginLocation(AddressUtils.getRealAddressByIP(ip));loginUser.setBrowser(userAgent.getBrowser().getName());loginUser.setOs(userAgent.getOperatingSystem().getName());
}
String userKey = getTokenKey(loginUser.getToken());
redisCache.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES);

Map<String, Object> claims = new HashMap<>();
claims.put(Constants.LOGIN_USER_KEY, token);
return createToken(claims);
private String createToken(Map<String, Object> claims)
{String token = Jwts.builder().setClaims(claims).signWith(SignatureAlgorithm.HS512, secret).compact();return token;
}
token:# 令牌自定义标识header: Authorization# 令牌密钥secret: xxx# 令牌有效期(默认30分钟)expireTime: 30
return createToken(claims);
doFilterInternal

https://zhuanlan.zhihu.com/p/342755411?utm medium=social&utm oi=1343915562263547904




/*** 匿名访问不鉴权注解**/
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Anonymous
{
}
PermitAllUrlProperties


https://cloud.tencentcom/document/product/400/35244




sudo /etc/init.d/bt default




加群联系作者vx:xiaoda0423
仓库地址:https://github.com/webVueBlog/JavaGuideInterview
相关文章:

springboot第25集:实体类定义规则
PO:持久化对象,一个PO对象对应一张表里面的一条记录。全部对应 VO:View视图对象,用来在页面中展示数据的,页面需要哪些字段属性就添加哪些,查询出来之后赋值操作比PO对象要简单。所以提高性能。 DTO&#x…...

【python】—— python的基本介绍并附安装教程
前言: 今天,我将给大家讲解关于python的基本知识,让大家对其有个基本的认识并且附上相应的安装教程以供大家参考。接下来,我们正式进入今天的文章!!! 目录 前言 (一)P…...

浏览器跨域请求
跨域是浏览器的一种同源策略,所以该概念只存在于通过浏览器访问服务里。 如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现 请求的url地址,必须与浏览器上的…...

什么,你还在用 momentJs 处理相对时间
我想,下面这段代码,你是不是在开发中常常这样使用来计算距离现在过去了多长时间: import moment from moment // 61k (gzipped:19.k) function Relative(props) {const timeString moment(props.date).fromNow()return <>{timeString…...
三维模型 工程图
飞机 Crankshaft飞机发动机手动冲压机包装成型机械-充填机械设备10数控等离子切割机床铜线缠绕机机床-磨床08机床-磨床04(附工程图)机床-车床数字纤维缠绕机机械臂液压钳机床-车床06挤出机机械手-09机械手模型库六柴油发动机中央空调机柜空调机机床-钻床三维设计电脑服务器机箱…...
我用ChatGPT写2023高考语文作文(二):全国乙卷
2023年 全国乙卷 适用地区:河南、江西、甘肃、青海、内蒙古、宁夏、新疆、陕西 吹灭别人的灯,并不会让自己更加光明;阻挡别人的路,也不会让自己行得更远。 “一花独放不是春,百花齐放春满园。”如果世界上只有一种花朵…...

java版本工程项目管理系统平台源码,助力工程企业实现数字化管理
鸿鹄工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离构建工程项目管理系统 1. 项目背景 一、随着公司的快速发展,企业人员和经营规模不断壮大。为了提高工程管理效率、减轻劳动强度、提高信息处理速度和准确性,公司对内部工程管…...

代码随想录第55天
1.判断子序列: 动态规划五部曲分析如下: 确定dp数组(dp table)以及下标的含义 dp[i][j] 表示以下标i-1为结尾的字符串s,和以下标j-1为结尾的字符串t,相同子序列的长度为dp[i][j]。 注意这里是判断s是否…...
算法设计与分析(填空专题)
文章目录 填空题填空题 设有一稀疏图 G,则 G 采用 邻接表 存储较省空间。 算法的时间复杂性是指算法中 元运算 执行次数。 分治法的基本思想是将一个规模为 n 的问题分解为与原问题 相同 的 k 个规模较小且互相独立的子问题。 贪心算法中每次做出的贪心选择都是 当前的 最优选…...
Ubuntu22.04 K8s1.27.2
Ubuntu22.04 && K8s1.27.2 1. 服务器配置 IpServerMEM192.168.56.11k8smaster6G192.168.56.16k8snode14G192.168.56.17k8snode24G 2. 获取源 $ sudo apt-get update $ sudo apt-get install -y apt-transport-https ca-certificates curl# packages.cloud.google.c…...

卡尔曼滤波与组合导航原理(十二)扩展卡尔曼滤波:EKF、二阶EKF、迭代EKF
文章目录 一、多元向量的泰勒级数展开二、扩展Kalman滤波三、二阶滤波四、迭代EKF滤波 一、多元向量的泰勒级数展开 { y 1 f 1 ( X ) f 1 ( x 1 , x 2 , ⋯ x n ) y 2 f 2 ( X ) f 2 ( x 1 , x 2 , ⋯ x n ) ⋮ y m f m ( X ) f m ( x 1 , x 2 , ⋯ x n ) \left\{\begin{…...

基于蒙特卡洛模拟法的电动汽车充电负荷研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...

自学黑客【网络安全】,一般人我劝你还是算了吧
一、自学网络安全学习的误区和陷阱 1.不要试图先成为一名程序员(以编程为基础的学习)再开始学习 我在之前的回答中,我都一再强调不要以编程为基础再开始学习网络安全,一般来说,学习编程不但学习周期长,而…...
编程中的心理策略:如何从错误中学习并实现自我成长
在日复一日的工作中,我们免不了会产生一些失误,会因此感到沮丧和失望。但如何正确地对待和处理这些失误才是最重要的,它直接影响到我们的工作表现和个人成长。 一、面对失误而带来的指责和沮丧的策略 在程序设计领域,我们经常面临…...

Rocket面试(五)Rocketmq发生流量控制的情况有哪些?
在使用rocketmq过程中总能看见一下异常 [TIMEOUT_CLEAN_QUEUE]broker busy, start flow control for a while, period in queue: 206ms, size of queue: 5这是因为Rocketmq出发了流量控制。 触发流量控制就是为了防止Broker压力过大挂掉。主要分为Broker流控,Consu…...

Tableau招聘信息数据可视化
获取的招聘信息数据为某招聘网站发布的大数据及数据分析相关岗位,对其他计算机相关岗位的招聘信息数据分析也有一定的参考价值。因为所获取的招聘信息数据数量只有1万左右,实际的招聘信息数量肯定不止1万,所以可能会与实际信息有一定的误差。…...
游戏服务器开发指南(八):合理应对异常
大家好!我是长三月,一位在游戏行业工作多年的老程序员,专注于分享服务器开发相关的文章。 本文是通用程序设计主题下的第二篇。这个主题主要探讨如何编写高效、健壮、易读的游戏业务代码,每篇从一个小点切入。本次讨论的要点是&a…...
【g】聚类算法之K-means算法
聚类算法是一种无监督学习方法,它将相似的数据样本划分为一组,同时将不相似的数据样本划分为另一组。这个过程由计算机自动完成,不需要任何人为的干预。 K-means算法是一种经典的聚类算法,它的主要思想是把数据集分成k个簇&#…...

scala内建控制结构
一、条件表达式 (一)语法格式 - if (条件) 值1 else 值2(二)执行情况 条件为真,结果是值1;条件为假,结果是值2。如果if和else的返回结果同为某种类型,那么条件表达式结果也是那种类…...

Linux SSH命令实战教程,提升你的服务器管理基本功!
前言 大家好,又见面了,我是沐风晓月,本文是专栏【linux基本功-基础命令实战】的第62篇文章。 专栏地址:[linux基本功-基础命令专栏] , 此专栏是沐风晓月对Linux常用命令的汇总,希望能够加深自己的印象&am…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...
五年级数学知识边界总结思考-下册
目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解:由来、作用与意义**一、知识点核心内容****二、知识点的由来:从生活实践到数学抽象****三、知识的作用:解决实际问题的工具****四、学习的意义:培养核心素养…...
蓝桥杯 冶炼金属
原题目链接 🔧 冶炼金属转换率推测题解 📜 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V,是一个正整数,表示每 V V V 个普通金属 O O O 可以冶炼出 …...

vulnyx Blogger writeup
信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面,gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress,说明目标所使用的cms是wordpress,访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...
4. TypeScript 类型推断与类型组合
一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式,自动确定它们的类型。 这一特性减少了显式类型注解的需要,在保持类型安全的同时简化了代码。通过分析上下文和初始值,TypeSc…...
为什么要创建 Vue 实例
核心原因:Vue 需要一个「控制中心」来驱动整个应用 你可以把 Vue 实例想象成你应用的**「大脑」或「引擎」。它负责协调模板、数据、逻辑和行为,将它们变成一个活的、可交互的应用**。没有这个实例,你的代码只是一堆静态的 HTML、JavaScript 变量和函数,无法「活」起来。 …...
关于uniapp展示PDF的解决方案
在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项: 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库: npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现指南针功能
指南针功能是许多位置服务应用的基础功能之一。下面我将详细介绍如何在HarmonyOS 5中使用DevEco Studio实现指南针功能。 1. 开发环境准备 确保已安装DevEco Studio 3.1或更高版本确保项目使用的是HarmonyOS 5.0 SDK在项目的module.json5中配置必要的权限 2. 权限配置 在mo…...

链式法则中 复合函数的推导路径 多变量“信息传递路径”
非常好,我们将之前关于偏导数链式法则中不能“约掉”偏导符号的问题,统一使用 二重复合函数: z f ( u ( x , y ) , v ( x , y ) ) \boxed{z f(u(x,y),\ v(x,y))} zf(u(x,y), v(x,y)) 来全面说明。我们会展示其全微分形式(偏导…...

高端性能封装正在突破性能壁垒,其芯片集成技术助力人工智能革命。
2024 年,高端封装市场规模为 80 亿美元,预计到 2030 年将超过 280 亿美元,2024-2030 年复合年增长率为 23%。 细分到各个终端市场,最大的高端性能封装市场是“电信和基础设施”,2024 年该市场创造了超过 67% 的收入。…...