SpringBoot项目搭建 + Jwt登录
临时接了一个小项目,有需要搭一个小项目,简单记录一下项目搭建过程以及整合登录功能。
1.首先拿到的是一个码云地址,里面是一个空的文件夹,只有一个

2. 拿到HTTPS码云项目地址链接,在IDEA中clone输入项目地址

3. 在项目根目录文件夹下右击,选择Add Frameworks Support, 添加maven框架支持

4. 然后得到pom.xml文件, 在pom文件中配置springboot
点击查看代码
<groupId>groupId</groupId>
<artifactId>resource-manager-background</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<artifactId>spring-boot-starter-parent</artifactId>
<groupId>org.springframework.boot</groupId>
<version>2.3.12.RELEASE</version>
</parent>
5. 引入其他相关依赖 mysql druid mybatisplus
点击查看代码
<dependencies>
<!-- mysqlconnect -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.1</version>
</dependency>
<!-- Mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.0</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.12</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.4.0</version>
</dependency>
<!-- jwt -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</dependency>
<!-- security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- springweb -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<swagger2.version>2.9.2</swagger2.version>
</properties>
6. 创建security文件夹,创建Security核心配置类
点击查看代码
package com.gameresource.security.config;
import com.gameresource.base.bean.Resp;
import com.gameresource.base.constant.RespConstant;
import com.gameresource.security.filter.JwtAuthTokenFilter;
import com.gameresource.security.util.RespUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private IgnoreUrlsConfig ignoreUrlsConfig;
@Override
protected void configure(HttpSecurity http) throws Exception {
ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = http.authorizeRequests();
for (String url : ignoreUrlsConfig.getUrls()) {
registry.antMatchers(url).permitAll();
}
registry.antMatchers(HttpMethod.OPTIONS).permitAll();
registry.and()
.authorizeRequests()
.anyRequest()
.authenticated()
//关闭跨站请求防护及不使用防护
.and()
.csrf()
.disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
//自定义权限拒绝处理类
.and()
.exceptionHandling()
.accessDeniedHandler(((request, response, accessDeniedException) -> {
RespUtils.outJson(response, Resp.code(RespConstant.NOT_PERMISSION));
}))
.authenticationEntryPoint((request, response, authenticationException) -> {
RespUtils.outJson(response, Resp.code(RespConstant.NOT_AUTHORIZE));
})
//自定义权限拦截器JWT过滤器
.and()
.addFilterBefore(jwtAuthTokenFilter(), UsernamePasswordAuthenticationFilter.class);
//关闭默认登录
http.formLogin().disable().httpBasic().disable();
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers(
"/auth/login",
"/doc.html",
"/swagger-ui.html",
"/v2/api-docs",
"/swagger-resources/**",
"/**/*.js",
"/**/*.css",
"/**/*.png",
"/**/*.ico"
);
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public JwtAuthTokenFilter jwtAuthTokenFilter() {
return new JwtAuthTokenFilter();
}
}
7. 自定义JWT过滤器
点击查看代码
package com.gameresource.security.filter;
import cn.hutool.core.util.StrUtil;
import com.gameresource.base.bean.Resp;
import com.gameresource.base.constant.RespConstant;
import com.gameresource.security.constant.SecurityConstant;
import com.gameresource.security.config.IgnoreUrlsConfig;
import com.gameresource.security.util.JwtTokenUtil;
import com.gameresource.security.util.RespUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 自定义JWT过滤器
*/
@Slf4j
public class JwtAuthTokenFilter extends OncePerRequestFilter {
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private IgnoreUrlsConfig ignoreUrlsConfig;
@Autowired
private JwtTokenUtil jwtTokenUtil;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
String authHeader = request.getHeader(SecurityConstant.TOKEN_HEADER);
String uri = request.getRequestURI();
if (StrUtil.startWith(authHeader, SecurityConstant.TOKEN_HEAD)) {
try {
String token = StrUtil.trim(authHeader.substring(SecurityConstant.TOKEN_HEAD.length()));
String username = jwtTokenUtil.getUserNameFromToken(token);
log.info("checking username:{}", username);
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
if (jwtTokenUtil.validateToken(token)) {
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
log.info("pass user: {}", username);
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
}
}
} catch (BadCredentialsException exception) {
RespUtils.outJson(response, Resp.fail(exception.getMessage()));
return;
} catch (Exception exception) {
log.error("Spring Security 校验异常: ", exception);
RespUtils.outJson(response, Resp.code(RespConstant.NOT_AUTHORIZE));
return;
}
}
chain.doFilter(request, response);
}
}
8. 创建JWT工具类
点击查看代码
package com.gameresource.security.util;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.gameresource.security.constant.SecurityConstant;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* jwt工具类
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class JwtTokenUtil {
@Value("${project.name}")
private String projectName;
@Value("${Jwt.secret}")
private String secret;
@Value("${Jwt.expiration}")
private Integer expiration;
private final StringRedisTemplate redisTemplate;
public boolean validateToken(String token) {
String username = getUserNameFromToken(token);
String redisKey = TokenRedisKeyUtils.installAuthToken(projectName, username);
if (Boolean.FALSE.equals(redisTemplate.hasKey(redisKey))) {
throw new BadCredentialsException("Token不存在或已过期");
}
String redisToken = redisTemplate.opsForValue().get(redisKey);
if (!StrUtil.equals(redisToken, token)) {
throw new BadCredentialsException("无效token");
}
return true;
}
/**
* 从token中获取用户名
*/
public String getUserNameFromToken(String token) {
return Convert.toStr(getValueFromToken(token, SecurityConstant.CLAIM_KEY_USERNAME));
}
private Object getValueFromToken(String token, String key) {
Claims claim = getClaimsFromToken(token);
return claim != null ? claim.get(key) : null;
}
private Claims getClaimsFromToken(String token) {
Claims claims = null;
try {
claims = Jwts.parser()
.setSigningKey(secret)
.parseClaimsJws(token)
.getBody();
} catch (Exception exception) {
log.error("jwt格式验证失败: {}", token);
}
return claims;
}
public String generateToken(UserDetails userDetails) {
return generateToken(userDetails, null);
}
private String generateToken(UserDetails userDetails, Map<String, Object> claims) {
if (claims == null) {
claims = new HashMap<>();
}
claims.put(SecurityConstant.CLAIM_KEY_USERNAME, userDetails.getUsername());
int ttl = expiration * 1000;
DateTime dateTime = DateUtil.offsetMillisecond(new Date(), ttl);
String token = Jwts.builder()
.setClaims(claims)
.setExpiration(dateTime)
.signWith(SignatureAlgorithm.HS256, secret)
.compact();
String redisKey = TokenRedisKeyUtils.installAuthToken(projectName, userDetails.getUsername());
redisTemplate.opsForValue().set(redisKey, token, ttl, TimeUnit.MILLISECONDS);
return token;
}
public Boolean removeToken(String username) {
return redisTemplate.delete(TokenRedisKeyUtils.installAuthToken(projectName, username));
}
}
9. 响应工具类
点击查看代码
package com.gameresource.security.util;
import com.alibaba.fastjson.JSON;
import com.gameresource.base.bean.Resp;
import org.springframework.http.MediaType;
import org.springframework.security.core.parameters.P;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class RespUtils {
public static void outJson(HttpServletResponse response, Resp resp) {
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
response.setStatus(HttpServletResponse.SC_OK);
response.setCharacterEncoding("utf-8");
try (PrintWriter printWriter = response.getWriter();) {
printWriter.print(JSON.toJSONString(resp));
printWriter.flush();
}catch (IOException exception) {
throw new RuntimeException();
}
}
}
10. UserDetailsService的自定义
点击查看代码
package com.gameresource.security.service;
import com.gameresource.manage.sys.SysUserManager;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class AuthUserDetailService implements UserDetailsService {
private final SysUserManager userManager;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
return userManager.findUserByName(username);
}
}
11. 各种类的实现代码
1. SysUserManager
点击查看代码
package com.gameresource.manage.sys;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.gameresource.module.sys.domain.AuthUser;
import com.gameresource.module.sys.entity.SysUserEntity;
import com.gameresource.module.sys.entity.SysUserRoleEntity;
import com.gameresource.module.sys.service.ISysUserRoleService;
import com.gameresource.module.sys.service.ISysUserService;
import com.gameresource.security.constant.SecurityConstant;
import com.gameresource.security.util.JwtTokenUtil;
import com.sun.org.apache.xpath.internal.operations.Bool;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.stream.Collectors;
@RequiredArgsConstructor
@Component
@Slf4j
public class SysUserManager {
private final ISysUserService userService;
@Autowired
private PasswordEncoder passwordEncoder;
private final ISysUserRoleService userRoleService;
private final JwtTokenUtil jwtTokenUtil;
public String login(String username, String password) {
UserDetails userDetails = findUserByName(username);
if (passwordEncoder.matches(password, userDetails.getPassword())) {
throw new BadCredentialsException("用户名或密码错误");
}
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
return jwtTokenUtil.generateToken(userDetails);
}
public UserDetails findUserByName(String username) {
SysUserEntity userEntity = userService.getByUsername(username);
if (ObjectUtil.isNull(userEntity)) {
throw new UsernameNotFoundException("用户不存在!");
}
if (!userEntity.getStatus()) {
throw new RuntimeException("此账户已被禁用!");
}
List<SysUserRoleEntity> roleEntityList = userRoleService.getByUserId(userEntity.getId());
List<Integer> roleList = roleEntityList.stream().map(SysUserRoleEntity::getRoleId).collect(Collectors.toList());
return AuthUser.create(userEntity, roleList, null);
}
public boolean logout(HttpServletRequest request) {
String token = request.getHeader(SecurityConstant.TOKEN_HEADER);
if (StrUtil.isBlank(token)) {
return false;
}
token = token.substring(SecurityConstant.TOKEN_HEAD.length());
String username = jwtTokenUtil.getUserNameFromToken(token);
Boolean logout = jwtTokenUtil.removeToken(username);
if (!logout) {
log.error("============登出失败============");
}
log.info("=======================用户退出{}======================", username);
return true;
}
}
2. AuthUser
点击查看代码
package com.gameresource.module.sys.domain;
import cn.hutool.core.collection.CollUtil;
import com.gameresource.module.sys.entity.SysUserEntity;
import lombok.Data;
import lombok.experimental.Accessors;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
@Data
@Accessors(chain = true)
public class AuthUser implements UserDetails {
/**
* 用户id
*/
private int userId;
/**
* 用户名
*/
private String username;
/**
* 密码
*/
private String password;
/**
* 是否启用
*/
private boolean status;
/**
* 用户角色列表
*/
private List<Integer> roleIds;
/**
* 用户权限列表
*/
private Collection<? extends GrantedAuthority> authorities;
public static UserDetails create(SysUserEntity sysUser, List<Integer> roleIds, List<String> perms) {
if (sysUser == null) {
return null;
}
List<GrantedAuthority> authorities = Collections.emptyList();
if (CollUtil.isNotEmpty(perms)) {
authorities = perms.stream().map(SimpleGrantedAuthority::new).collect(Collectors.toList());
}
return new AuthUser()
.setUserId(sysUser.getId())
.setStatus(sysUser.getStatus())
.setUsername(sysUser.getUsername())
.setPassword(sysUser.getPassword())
.setRoleIds(CollUtil.isNotEmpty(roleIds) ? roleIds : Collections.emptyList())
.setAuthorities(authorities);
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return null;
}
@Override
public String getPassword() {
return password;
}
@Override
public String getUsername() {
return username;
}
@Override
public boolean isAccountNonExpired() {
return false;
}
@Override
public boolean isAccountNonLocked() {
return false;
}
@Override
public boolean isCredentialsNonExpired() {
return false;
}
@Override
public boolean isEnabled() {
return status;
}
}
12. 登录接口
点击查看代码
package com.gameresource.web.sys;
import cn.hutool.core.lang.Assert;
import com.gameresource.base.bean.Resp;
import com.gameresource.manage.sys.SysUserManager;
import com.gameresource.module.sys.domain.AuthUser;
import com.gameresource.module.sys.domain.AuthUserVo;
import com.gameresource.module.sys.domain.LoginReqDto;
import com.gameresource.util.SecurityUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
@Slf4j
@Api(tags = "登录")
@RestController
@RequestMapping("/auth")
@RequiredArgsConstructor
public class LoginController {
private final SysUserManager sysUserManager;
@ApiOperation("用户登录")
@PostMapping("/login")
public Resp<AuthUserVo> login(@Valid @RequestBody LoginReqDto loginReq) {
try {
log.info("===============loginReq=====================username:[{}],password:[{}]",loginReq.getUsername(), loginReq.getPassword());
String token = sysUserManager.login(loginReq.getUsername(), loginReq.getPassword());
Assert.notBlank(token, "用户名或密码错误");
AuthUser authUser = SecurityUtil.getCurrentUser();
log.info("========================用户{}登录成功!=============================", authUser.getUsername());
return Resp.ok(AuthUserVo.create(authUser, token));
}catch (Exception e) {
log.info("登录失败: ", e);
return Resp.fail(e.getMessage());
}
}
@ApiOperation("用户退出")
@PostMapping("/logout")
public Resp<Boolean> logout(HttpServletRequest request) {
return Resp.result(sysUserManager.logout(request));
}
}
13. 至此结束
其实登录的核心部分就是WebSecurityConfigurerAdapter下的configure方法,我们通过自定义了一个SecurityConfig类来继承了WebSecurityConfigurerAdapter类,并重写配置类的各种选项达到自定义的效果,另外一个就是OncePerRequestFilter来过滤各种请求,在这里我们会处理请求并验证token,这只是项目中比较简单的一种写法,另外security还有很多其他的配置,在这里只是列举了其中的一种较为简单的方式,才疏学浅,还需要多加学习,共勉!
SpringBoot项目搭建 + Jwt登录的更多相关文章
- SpringBoot 项目搭建(详细介绍+案例源码)
SpringBoot 项目搭建 SpringBoot 项目整合源码 SpringBoot 项目整合 一.项目准备 1.1 快速创建 SpringBoot 项目 1.2 标准项目结构图如下 1.3 添加 ...
- SpringBoot之入门教程-SpringBoot项目搭建
SpringBoot大大的简化了Spring的配置,把Spring从配置炼狱中解救出来了,以前天天配置Spring和Mybatis,Springmvc,Hibernate等整合在一起,感觉用起来还是挺 ...
- SpringBoot项目搭建与打包
一.环境准备 本地java环境jdk1.8 Maven版本3.5.2 IDE工具idea2017 二.SpringBoot微服务搭建 1.点击File >> New >> Pr ...
- springboot系列二、springboot项目搭建
一.官网快速构建 1.maven构建项目 1.访问http://start.spring.io/ 2.选择构建工具Maven Project.Spring Boot版本2.1.1以及一些工程基本信息, ...
- 从零开始的SpringBoot项目搭建
前言 今天是我加入博客园的第一天今天刚好学习到SpringBoot,就顺便记录一下吧 一.创建项目 1.创建工程 ① 通过File > New > Project,新建工程,选择Sprin ...
- Springboot项目搭建(3)-shiro登录
shiro简述+实现简单登录:https://www.jianshu.com/p/7f724bec3dc3
- springboot项目搭建及常用技术整合
一.在你建立的工程下创建 Module 选择Spring initializr创建. 二.在Type处选择: Maven Project(项目的构建工具) 三.创建依赖时勾上web,mybatis,m ...
- oa_mvc_easyui_项目搭建及登录页面验证码(1)
1.空项目的搭建,三层的搭建(各层之中的引用) webapp:bll,model,common bll:dal,model dal:model 2.SQL表 ItcastDb:T_UserInfo,T ...
- springboot项目搭建:结构和入门程序
Spring Boot 推荐目录结构 代码层的结构 根目录:com.springboot 1.工程启动类(ApplicationServer.java)置于com.springboot.build包下 ...
随机推荐
- 【抬杠C#】如何实现接口的base调用
背景 在三年前发布的C#8.0中有一项重要的改进叫做接口默认实现,从此以后,接口中定义的方法可以包含方法体了,即默认实现.不过对于接口的默认实现,其实现类或者子接口在重写这个方法的时候不能对其进行ba ...
- 工作流引擎之Elsa入门系列教程之一 初始化项目并创建第一个工作流
引子 工作流(Workflow)是对工作流程及其各操作步骤之间业务规则的抽象.概括描述. 为了实现某个业务目标,需要多方参与.按预定规则提交数据时,就可以用到工作流. 通过流程引擎,我们按照流程图,编 ...
- 聊聊C#中的composite模式
写在前面 Composite组合模式属于设计模式中比较热门的一个,相信大家对它一定不像对访问者模式那么陌生,毕竟谁又没有遇到过树形结构呢.不过所谓温故而知新,我们还是从一个例子出发,起底一下这个模式吧 ...
- 快速全面了解QT软件界面开发技术
快速全面了解QT软件界面开发技术 目录 前言 一. 学习QT可能的目的是什么? 只想体验一下QT? 当前的项目选择了用QT. 为将来做QT技术储备. 二. QT的核心技术优势是什么? QT在软 ...
- 记一次APP渗透登录验证绕过思路
前言: 起初是抓包时候查看返回状态码不一致,所以觉得是否可以通过修改状态码来达到绕过的目的,但是拦截响应包再替换手速不够,技术大哥就去搜了下,找到了一个方法,可以自动替换响应包内容. 在偏下方一点的地 ...
- Python基础学习笔记_01
Python的介绍 1989年圣诞节创造,1991年正真出生,目前更新到3.0版本 具有最庞大的"代码库",人称"胶水语言",无所不能 一种跨平台的计算机程序设 ...
- RPA应用场景-银行回单查询
场景概述银行回单查询 所涉系统名称银行网银 人工操作(时间/次) 5 分钟 所涉人工数量 4 操作频率不定时 场景流程 1.收到外派业务员申请查询收入银行回单的邮件: 2.依据邮件中提供的客户信息进入 ...
- Linux文件的删除和软硬链接
文件的构成 由元数据(metadata)和数据(data)两部分组成 硬盘分区上一块空间存该分区上文件的元数据,一块空间存这些文件的数据 因为元数据和数据分离存放,所以需要通过指针地址来进行关联 元数 ...
- python:**也不过如此嘛,这不也被我采集下来啦~
前言 嗨喽!大家好呀,这里是小熊猫 知识点: 基本流程 fiddler抓包 开发环境: python 3.8 运行代码 pycharm 2021.2 辅助敲代码 requests 第三方模块 如果安装 ...
- 攻防世界pwn题:Recho
0x00:查看文件信息 一个64位二进制文件,canary和PIE保护机制没开. 0x01:用IDA进行静态分析 分析:主程序部分是一个while循环,判断条件是read返回值大于0则循环.函数ato ...