首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >springboot第25集:实体类定义规则

springboot第25集:实体类定义规则

作者头像
达达前端
发布2023-10-08 18:34:16
发布2023-10-08 18:34:16
36400
代码可运行
举报
文章被收录于专栏:达达前端达达前端
运行总次数:0
代码可运行

PO:持久化对象,一个PO对象对应一张表里面的一条记录。全部对应

VO:View视图对象,用来在页面中展示数据的,页面需要哪些字段属性就添加哪些,查询出来之后赋值操作比PO对象要简单。所以提高性能。

DTO:数据传递对象,如果要查询的结果集有多张表,或者从多个表获得的数据就可以封装DTO对象,把这些表的数据全部封装到一起,形成一个对象。

POJO:中间形态,可以在PO,VO,DTO之间互相转换。

POJO在保存数据,PO

POJO在表示层,VO

POJO数据传递,DTO

代码语言:javascript
代码运行次数:0
运行
复制
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
{
    @Autowired
    private SysLoginService loginService;

    @Autowired
    private ISysMenuService menuService;

    @Autowired
    private 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));
    }
}
代码语言:javascript
代码运行次数:0
运行
复制
//        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字段里面。

代码语言:javascript
代码运行次数:0
运行
复制
private String createToken(Map<String, Object> claims) {
 String token = Jwts.builder().setClaims(claims).signWith(SignatureAlgorithm.HS512,secret).compact();
 return token;
}

image.png

image.png

代码语言:javascript
代码运行次数:0
运行
复制
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);
}
代码语言:javascript
代码运行次数:0
运行
复制
tokenService.getLoginUser(request);
代码语言:javascript
代码运行次数:0
运行
复制
Claims claims = parseToken(token);
代码语言:javascript
代码运行次数:0
运行
复制
private Claims parseToken(String token)
{
    return Jwts.parser()
            .setSigningKey(secret)
            .parseClaimsJws(token)
            .getBody();
}
代码语言:javascript
代码运行次数:0
运行
复制
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;
}

image.png

代码语言:javascript
代码运行次数:0
运行
复制
const whiteList = [];
router.beforeEach((to, from, next) => {
 NProgress.start()
 if (getToken
})
代码语言:javascript
代码运行次数:0
运行
复制
<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>

添加一个配置类,配置拦截的路径

代码语言:javascript
代码运行次数:0
运行
复制
@Configuration
public class SecurityConfig extends WebSecurityConfigureAdapter {
 @Override
 protected void configure(HttpSecurity http) throws Exception {
  http.formLogin() // 表单登录
      .add()
      .authorizeRequests() // 认证配置
      .anyRequest() // 任何请求
      .authenticated(); // 需要身份验证
 }
}

编写一个简单的controller测试

代码语言:javascript
代码运行次数:0
运行
复制
@RequestMapping("hello")
@RestController
public class HelloController {
 @GetMapping("test")
 public String test() {
  return "spring security";
 }
}

image.png

(1)JWT 默认是不加密,但也是可以加密的。生成原始 Token 以后,可以用密钥再加密一次。

(2)JWT 不加密的情况下,不能将秘密数据写入 JWT。

(3)JWT 不仅可以用于认证,也可以用于交换信息。有效使用 JWT,可以降低服务器查询数据库的次数。

(4)JWT 的最大缺点是,由于服务器不保存 session 状态,因此无法在使用过程中废止某个 token,或者更改 token 的权限。也就是说,一旦 JWT 签发了,在到期之前就会始终有效,除非服务器部署额外的逻辑。

(5)JWT 本身包含了认证信息,一旦泄露,任何人都可以获得该令牌的所有权限。为了减少盗用,JWT 的有效期应该设置得比较短。对于一些比较重要的权限,使用时应该再次对用户进行认证。

(6)为了减少盗用,JWT 不应该使用 HTTP 协议明码传输,要使用 HTTPS 协议传输。

代码语言:javascript
代码运行次数:0
运行
复制
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter
{
    @Bean
    @Override
    protected AuthenticationManager authenticationManager() throws Exception {
        return super.authenticationManager();
    }
}

Authentication authentication = SecurityContextHolder.getContext().getAuthentication()
代码语言:javascript
代码运行次数:0
运行
复制
/**
 * 获取Authentication
 */
public static Authentication getAuthentication()
{
    return SecurityContextHolder.getContext().getAuthentication();
}

Authentication: 存储了认证信息,代表当前登录用户

SeucirtyContext: 上下文对象,用来获取Authentication

SecurityContextHolder: 上下文管理对象,用来在程序任何地方获取SecurityContext

代码语言:javascript
代码运行次数:0
运行
复制
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception
{
    return super.authenticationManagerBean();
}
代码语言:javascript
代码运行次数:0
运行
复制
@RestController
@RequestMapping("/API")
public class LoginController {
    @Autowired
    private AuthenticationManager authenticationManager;

    @PostMapping("/login")
    public String login(@RequestBody LoginParam param) {
        // 生成一个包含账号密码的认证信息
        Authentication token = new UsernamePasswordAuthenticationToken(param.getUsername(), param.getPassword());
        // AuthenticationManager校验这个认证信息,返回一个已认证的Authentication
        Authentication authentication = authenticationManager.authenticate(token);
        // 将返回的Authentication存到上下文中
        SecurityContextHolder.getContext().setAuthentication(authentication);
        return "登录成功";
    }
}
代码语言:javascript
代码运行次数:0
运行
复制
@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 "注册成功";
}

认证管理器,调用,认证方法

image.png

代码语言:javascript
代码运行次数:0
运行
复制
try
{
    UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
    AuthenticationContextHolder.setContext(authenticationToken);
    // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
    authentication = authenticationManager.authenticate(authenticationToken);
}
代码语言:javascript
代码运行次数:0
运行
复制
@Service
public class UserDetailsServiceImpl implements UserDetailsService
{
}
代码语言:javascript
代码运行次数:0
运行
复制
@Resource
private AuthenticationManager authenticationManager;

调用这个认证方法

代码语言:javascript
代码运行次数:0
运行
复制
authenticate
代码语言:javascript
代码运行次数:0
运行
复制
SysUser user = userService.selectUserByUserName(username);

通过用户名查询用户

image.png

代码语言:javascript
代码运行次数:0
运行
复制
/**
 * 强散列哈希加密实现
 */
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder()
{
    return new BCryptPasswordEncoder();
}

/**
 * 身份认证接口
 */
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception
{
    auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
}

image.png

loadUserByUsername

代码语言:javascript
代码运行次数:0
运行
复制
SysUser user = userService.selectUserByUserName(username);
代码语言:javascript
代码运行次数:0
运行
复制
@Override
public SysUser selectUserByUserName(String userName)
{
    return userMapper.selectUserByUserName(userName);
}
代码语言:javascript
代码运行次数:0
运行
复制
public SysUser selectUserByUserName(String userName);

image.png

代码语言:javascript
代码运行次数:0
运行
复制
public class LoginUser implements UserDetails
{
}
代码语言:javascript
代码运行次数:0
运行
复制
{
    this.userId = userId;
    this.deptId = deptId;
    this.user = user;
    this.permissions = permissions;
}
代码语言:javascript
代码运行次数:0
运行
复制
public UserDetails createLoginUser(SysUser user)
{
    return new LoginUser(user.getUserId(), user.getDeptId(), user, permissionService.getMenuPermission(user));
}
代码语言:javascript
代码运行次数:0
运行
复制
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();
}

image.png

image.png

代码语言:javascript
代码运行次数:0
运行
复制
private ScheduledExecutorService executor = SpringUtils.getBean("scheduledExecutorService");
代码语言:javascript
代码运行次数:0
运行
复制
LoginUser loginUser = (LoginUser) authentication.getPrincipal();
recordLoginInfo(loginUser.getUserId());
// 生成token
return tokenService.createToken(loginUser);
代码语言:javascript
代码运行次数:0
运行
复制
/**
 * 设置用户代理信息
 *
 * @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());
}
代码语言:javascript
代码运行次数:0
运行
复制
String userKey = getTokenKey(loginUser.getToken());
redisCache.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES);

image.png

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

doFilterInternal

image.png

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

image.png

image.png

image.png

image.png

代码语言:javascript
代码运行次数:0
运行
复制
/**
 * 匿名访问不鉴权注解
 *
 */
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Anonymous
{
}

PermitAllUrlProperties

image.png

image.png

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

image.png

image.png

image.png

image.png

代码语言:javascript
代码运行次数:0
运行
复制
sudo /etc/init.d/bt default

image.png

image.png

image.png

image.png

仓库地址:https://github.com/webVueBlog/JavaGuideInterview

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-06-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档