做产品推广有网站比较好的,手机网站制作优化,嘉兴网站建设与管理专业,创建全国文明城市工作总结PO#xff1a;持久化对象#xff0c;一个PO对象对应一张表里面的一条记录。全部对应 VO#xff1a;View视图对象#xff0c;用来在页面中展示数据的#xff0c;页面需要哪些字段属性就添加哪些#xff0c;查询出来之后赋值操作比PO对象要简单。所以提高性能。 DTO#x… PO持久化对象一个PO对象对应一张表里面的一条记录。全部对应 VOView视图对象用来在页面中展示数据的页面需要哪些字段属性就添加哪些查询出来之后赋值操作比PO对象要简单。所以提高性能。 DTO数据传递对象如果要查询的结果集有多张表或者从多个表获得的数据就可以封装DTO对象把这些表的数据全部封装到一起形成一个对象。 POJO中间形态可以在POVODTO之间互相转换。 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();// 角色集合SetString roles permissionService.getRolePermission(user);// 权限集合SetString 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();ListSysMenu 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/?tokenxxx。Base64 有三个字符、/和在 URL 里面有特殊含义所以要被替换掉被省略、替换成-/替换成_ 。这就是 Base64URL 算法。 客户端收到服务器返回的 JWT可以储存在 Cookie 里面也可以储存在 localStorage。 此后客户端每次与服务器通信都要带上这个 JWT。你可以把它放在 Cookie 里面自动发送但是这样不能跨域所以更好的做法是放在 HTTP 请求的头信息Authorization字段里面。 private String createToken(MapString, Object claims) {String token Jwts.builder().setClaims(claims).signWith(SignatureAlgorithm.HS512,secret).compact();return token;
} image.png image.png public String createToken(LoginUser loginUser)
{String token IdUtils.fastUUID();loginUser.setToken(token);setUserAgent(loginUser);refreshToken(loginUser);MapString, 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;
} image.png const whiteList [];
router.beforeEach((to, from, next) {NProgress.start()if (getToken
}) dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-security/artifactId
/dependency
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-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;}
} image.png 1JWT 默认是不加密但也是可以加密的。生成原始 Token 以后可以用密钥再加密一次。 2JWT 不加密的情况下不能将秘密数据写入 JWT。 3JWT 不仅可以用于认证也可以用于交换信息。有效使用 JWT可以降低服务器查询数据库的次数。 4JWT 的最大缺点是由于服务器不保存 session 状态因此无法在使用过程中废止某个 token或者更改 token 的权限。也就是说一旦 JWT 签发了在到期之前就会始终有效除非服务器部署额外的逻辑。 5JWT 本身包含了认证信息一旦泄露任何人都可以获得该令牌的所有权限。为了减少盗用JWT 的有效期应该设置得比较短。对于一些比较重要的权限使用时应该再次对用户进行认证。 6为了减少盗用JWT 不应该使用 HTTP 协议明码传输要使用 HTTPS 协议传输。 EnableGlobalMethodSecurity(prePostEnabled true, securedEnabled true)
public class SecurityConfig extends WebSecurityConfigurerAdapter
{BeanOverrideprotected 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 注册成功;
} 认证管理器调用认证方法 image.png 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); 通过用户名查询用户 image.png /*** 强散列哈希加密实现*/
Bean
public BCryptPasswordEncoder bCryptPasswordEncoder()
{return new BCryptPasswordEncoder();
}/*** 身份认证接口*/
Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception
{auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
} image.png loadUserByUsername SysUser user userService.selectUserByUserName(username); Override
public SysUser selectUserByUserName(String userName)
{return userMapper.selectUserByUserName(userName);
} public SysUser selectUserByUserName(String userName); image.png 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, SetString 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 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); image.png MapString, Object claims new HashMap();
claims.put(Constants.LOGIN_USER_KEY, token);
return createToken(claims); private String createToken(MapString, 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 image.png https://zhuanlan.zhihu.com/p/342755411?utm mediumsocialutm oi1343915562263547904 image.png image.png image.png image.png /*** 匿名访问不鉴权注解**/
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 sudo /etc/init.d/bt default image.png image.png image.png image.png 加群联系作者vxxiaoda0423 仓库地址https://github.com/webVueBlog/JavaGuideInterview