第6章-密码加密与微服务鉴权JWT

学习目标:

**
能够使用BCrypt密码加密算法实现注册与登陆功能
能够说出常见的认证机制
能够说出JWT的组成部分,以及使用JWT的优点
能够使用JJWT
创建和解析token 能够使用JJWT完成微服务鉴权**

1 BCrypt密码加密

1.1 准备工作
任何应用考虑到安全,绝不能明文的方式保存密码。密码应该通过哈希算法进行加密。 有很多标准的算法比如SHA或者MD5,结合salt(盐)是一个不错的选择。 Spring Security 提供了BCryptPasswordEncoder类,实现Spring的PasswordEncoder接口使用BCrypt强 哈希方法来加密密码。
BCrypt强哈希方法 每次加密的结果都不一样。
(1)tensquare_user工程的pom引入依赖

<dependency> 
<groupId>org.springframework.boot</groupId> 
<artifactId>spring‐boot‐starter‐security</artifactId> 
</dependency>

(2)添加配置类 (资源/工具类中提供)
我们在添加了spring security依赖后,所有的地址都被spring security所控制了,我们目 前只是需要用到BCrypt密码加密的部分,所以我们要添加一个配置类,配置为所有地址 都可以匿名访问。

/*** 安全配置类 */ 
@Configuration 
@EnableWebSecurity 
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{ @Override 
protected void configure(HttpSecurity http) throws Exception { 
http 
.authorizeRequests() 
.antMatchers("/**").permitAll() 
.anyRequest().authenticated() 
.and().csrf().disable(); 
} 
}

(3)修改tensquare_user工程的Application, 配置bean

@Bean 
public BCryptPasswordEncoder bcryptPasswordEncoder(){ 
return new BCryptPasswordEncoder(); 
}

1.2 管理员密码加密

1.2.1 新增管理员密码加密
修改tensquare_user工程的AdminService

@Autowired 
BCryptPasswordEncoder encoder; 
public void add(Admin admin) { 
admin.setId(idWorker.nextId()+""); //主键值 //密码加密 
String newpassword = encoder.encode(admin.getPassword());//加密后 的密码 admin.setPassword(newpassword); 
adminDao.save(admin); }

1.2.2 管理员登陆密码校验
(1)AdminDao增加方法定义

public Admin findByLoginname(String loginname);

(2)AdminService增加方法

/*** 根据登陆名和密码查询 * @param loginname * @param password * @return */ public Admin findByLoginnameAndPassword(String loginname, String password){
Admin admin = adminDao.findByLoginname(loginname); 
if( admin!=null && encoder.matches(password,admin.getPassword())) { 
return admin; }
else{
return null; 
} 
}

(3)AdminController增加方法

/*** 用户登陆 * @param loginname * @param password * @return */ @RequestMapping(value="/login",method=RequestMethod.POST) 
public Result login(@RequestBody Map<String,String> loginMap){ 
Admin admin = adminService.findByLoginnameAndPassword(loginMap.get("loginname"), loginMap.get("password")); 
if(admin!=null){ 
return new Result(true,StatusCode.OK,"登陆成功"); 
}else{
return new Result(false,StatusCode.LOGINERROR,"用户名或密码错 误"); 
} 
}

1.3 用户密码加密

1.3.1 用户注册密码加密
(4)修改tensquare_user工程的UserService 类,引入BCryptPasswordEncoder

@Autowired 
BCryptPasswordEncoder encoder;

(5)修改tensquare_user工程的UserService 类的add方法,添加密码加密的逻辑

/** * 增加 * @param user * @param code */ 
public void add(User user,String code) { ........ ........ ........ //密码加密 String newpassword = encoder.encode(user.getPassword());//加密后的 密码 user.setPassword(newpassword); 
userDao.save(user); 
}

(4)测试运行后,添加数据

{ "mobile": "13901238899" "password": "123123", }

数据库中的密码为以下形式

$2a$10$a/EYRjdKwQ6zjr0/HJ6RR.rcA1dwv1ys7Uso1xShUaBWlIWTyJl5S

1.3.2 用户登陆密码判断
(1)修改tensquare_user工程的UserDao接口,增加方法定义

/** * 根据手机号查询用户 * @param mobile * @return */ 
public User findByMobile(String mobile);

(2)修改tensquare_user工程的UserService 类,增加方法

/*** 根据手机号和密码查询用户 * @param mobile * @param password * @return */ public User findByMobileAndPassword(String mobile,String password){ 
User user = userDao.findByMobile(mobile); 
if(user!=null && encoder.matches(password,user.getPassword())){ 
return user; }else{return null; } }

(4)修改tensquare_user工程的UserController类,增加login方法

/*** 用户登陆 * @param mobile * @param password * @return */ @RequestMapping(value="/login",method=RequestMethod.POST) 
public Result login(String mobile,String password){ 
User user = userService.findByMobileAndPassword(mobile,password); if(user!=null){ 
return new Result(true,StatusCode.OK,"登陆成功"); }
else{return new Result(false,StatusCode.LOGINERROR,"用户名或密码错 误"); } }

(4)使用刚才新增加的账号进行测试,查看返回结果

2 常见的认证机制

2.1 HTTP Basic Auth
HTTP Basic Auth简单点说明就是每次请求API时都提供用户的username和 password,简言之,Basic Auth是配合RESTful API 使用的最简单的认证方式,只需提供 用户名密码即可,但由于有把用户名密码暴露给第三方客户端的风险,在生产环境下被 使用的越来越少。因此,在开发对外开放的RESTful API时,尽量避免采用HTTP Basic Auth
2.2 Cookie Auth
Cookie认证机制就是为一次请求认证在服务端创建一个Session对象,同时在客户端 的浏览器端创建了一个Cookie对象;通过客户端带上来Cookie对象来与服务器端的 session对象匹配来实现状态管理的。默认的,当我们关闭浏览器的时候,cookie会被删 除。但可以通过修改cookie 的expire time使cookie在一定时间内有效;
在这里插入图片描述

2.3 OAuth

  OAuth(开放授权)是一个开放的授权标准,允许用户让第三方应用访问该用户在 某一web服务上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和 密码提供给第三方应用。OAuth允许用户提供一个令牌,而不是用户名和密码来访问他们存放在特定服务提 供者的数据。每一个令牌授权一个特定的第三方系统(例如,视频编辑网站)在特定的时 段(例如,接下来的2小时内)内访问特定的资源(例如仅仅是某一相册中的视频)。这 样,OAuth让用户可以授权第三方网站访问他们存储在另外服务提供者的某些特定信 息,而非所有内容

在这里插入图片描述
这种基于OAuth的认证机制适用于个人消费者类的互联网产品,如社交类APP等应 用,但是不太适合拥有自有认证权限管理的企业应用。

2.4 Token Auth

使用基于 Token 的身份验证方法,在服务端不需要存储用户的登录记录。大概的流程是 这样的: 1. 客户端使用用户名跟密码请求登录
2. 服务端收到请求,去验证用户名与密码
3. 验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端
4. 客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里
5. 客户端每次向服务端请求资源的时候需要带着服务端签发的 Token
6. 服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向 客户端返回请求的数据
在这里插入图片描述
Token Auth的优点 T
oken机制相对于Cookie机制又有什么好处呢?
支持跨域访问: Cookie是不允许垮域访问的,这一点对Token机制是不存在的,前提 是传输的用户认证信息通过HTTP头传输.
无状态(也称:服务端可扩展行):Token机制在服务端不需要存储session信息,因为 Token 自身包含了所有登录用户的信息,只需要在客户端的cookie或本地介质存储 状态信息.
更适用CDN: 可以通过内容分发网络请求你服务端的所有资料(如:javascript, HTML,图片等),而你的服务端只要提供API即可.
去耦: 不需要绑定到一个特定的身份验证方案。Token可以在任何地方生成,只要在 你的API被调用的时候,你可以进行Token生成调用即可.
更适用于移动应用: 当你的客户端是一个原生平台(iOS, Android,Windows 8等) 时,Cookie是不被支持的(你需要通过Cookie容器进行处理),这时采用Token认 证机制就会简单得多。 CSRF:因为不再依赖于Cookie,所以你就不需要考虑对CSRF(跨站请求伪造)的防 范。
性能: 一次网络往返时间(通过数据库查询session信息)总比做一次HMACSHA256 计算 的Token验证和解析要费时得多.
不需要为登录页面做特殊处理: 如果你使用Protractor 做功能测试的时候,不再需要 为登录页面做特殊处理.
基于标准化:你的API可以采用标准化的 JSON Web Token (JWT). 这个标准已经存在 多个后端库(.NET, Ruby, Java,Python, PHP)和多家公司的支持(如: Firebase,Google, Microsoft).

3 基于JWT的Token认证机制实现

3.1 什么是JWT

JSON Web Token(JWT)是一个非常轻巧的规范。这个规范允许我们使用JWT在用 户和服务器之间传递安全可靠的信息。

3.2 JWT组成

一个JWT实际上就是一个字符串,它由三部分组成,头部、载荷与签名。 头部(Header) 头部用于描述关于该JWT的最基本的信息,例如其类型以及签名所用的算法等。这也可以 被表示成一个JSON对象。

{"typ":"JWT","alg":"HS256"}

在头部指明了签名算法是HS256算法。 我们进行BASE64编 码http://base64.xpcha.com/,编码后的字符串如下:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9

在这里插入图片描述
载荷(playload)
载荷就是存放有效信息的地方。这个名字像是特指飞机上承载的货品,这些有效信息包 含三个部分
(1)标准中注册的声明(建议但不强制使用)

iss: jwt签发者 
sub: jwt所面向的用户 
aud: 接收jwt的一方 
exp: jwt的过期时间,这个过期时间必须要大于签发时间 
nbf: 定义在什么时间之前,该jwt都是不可用的. 
iat: jwt的签发时间 
jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。

(2)公共的声明
公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息. 但不建议添加敏感信息,因为该部分在客户端可解密.
(3)私有的声明
私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为base64 是对称解密的,意味着该部分信息可以归类为明文信息。 这个指的就是自定义的claim。比如前面那个结构举例中的admin和name都属于自定的 claim。这些claim跟JWT标准规定的claim区别在于:JWT规定的claim,JWT的接收方在 拿到JWT之后,都知道怎么对这些标准的claim进行验证(还不知道是否能够验证);而 private claims不会验证,除非明确告诉接收方要对这些claim进行验证以及规则才行。
定义一个payload:

{"sub":"1234567890","name":"John Doe","admin":true}

然后将其进行base64编码,得到Jwt的第二部分。

eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9

签证(signature)
jwt的第三部分是一个签证信息,这个签证信息由三部分组成:
在这里插入图片描述
这个部分需要base64加密后的header和base64加密后的payload使用.连接组成的字符 串,然后通过header中声明的加密方式进行加盐secret组合加密,然后就构成了jwt的第 三部分。

TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

将这三部分用.连接成一个完整的字符串,构成了最终的jwt:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6I kpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7Hg Q

注意:secret是保存在服务器端的,jwt的签发生成也是在服务器端的,secret就是用 来进行jwt的签发和jwt的验证,所以,它就是你服务端的私钥,在任何场景都不应该流 露出去。一旦客户端得知这个secret, 那就意味着客户端是可以自我签发jwt了。

4 Java的JJWT实现JWT

4.1 什么是JJWT

   JJWT是一个提供端到端的JWT创建和验证的Java库。永远免费和开源(Apache License,版本2.0),JJWT很容易使用和理解。它被设计成一个以建筑为中心的流畅界 面,隐藏了它的大部分复杂性。

4.2 JJWT快速入门

4.2.1 token的创建
(1)创建maven工程,引入依赖

<dependency> 
<groupId>io.jsonwebtoken</groupId> 
<artifactId>jjwt</artifactId> 
<version>0.6.0</version> 
</dependency>

(2)创建类CreateJwtTest,用于生成token

public class CreateJwtTest { 
public static void main(String[] args) { JwtBuilder builder= Jwts.builder().setId("888") .setSubject("小白") .setIssuedAt(new Date()) .signWith(SignatureAlgorithm.HS256,"itcast"); 
System.out.println( builder.compact() ); } }

setIssuedAt用于设置签发时间
signWith用于设置签名秘钥
(3)测试运行,输出如下:

eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4ODgiLCJzdWIiOiLlsI_nmb0iLCJpYXQiOjE1MjM0M TM0NTh9.gq0J‐cOM_qCNqU_s‐d_IrRytaNenesPmqAIhQpYXHZk

再次运行,会发现每次运行的结果是不一样的,因为我们的载荷中包含了时间。
4.2.2 token的解析
我们刚才已经创建了token ,在web应用中这个操作是由服务端进行然后发给客户 端,客户端在下次向服务端发送请求时需要携带这个token(这就好像是拿着一张门票一 样),那服务端接到这个token 应该解析出token中的信息(例如用户id),根据这些信息 查询数据库返回相应的结果。 创建ParseJwtTest

public class ParseJwtTest { 
public static void main(String[] args) { 
String token="eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4ODgiLCJzdWIiOiLlsI_nmb0iLCJpYXQiO jE1MjM0MTM0NTh9.gq0J‐cOM_qCNqU_s‐d_IrRytaNenesPmqAIhQpYXHZk"; 
Claims claims = Jwts.parser().setSigningKey("itcast").parseClaimsJws(token).getBody(); System.out.println("id:"+claims.getId()); System.out.println("subject:"+claims.getSubject()); System.out.println("IssuedAt:"+claims.getIssuedAt()); 
} 
}

4.2.3 token过期校验
有很多时候,我们并不希望签发的token是永久生效的,所以我们可以为token添加一个 过期时间。 创建CreateJwtTest2

public class CreateJwtTest2 { 
public static void main(String[] args) { 
//为了方便测试,我们将过期时间设置为1分钟 
long now = System.currentTimeMillis();//当前时间 
long exp = now + 1000*60;//过期时间为1分钟 
JwtBuilder builder= Jwts.builder().setId("888") .setSubject("小白") .setIssuedAt(new Date()) .signWith(SignatureAlgorithm.HS256,"itcast") .setExpiration(new Date(exp)); System.out.println( builder.compact() ); } }

setExpiration 方法用于设置过期时间
修改ParseJwtTest

public class ParseJwtTest { 
public static void main(String[] args) { 
String compactJws="eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4ODgiLCJzdWIiOiLlsI_nmb0iLCJp YXQiOjE1MjM0MTY1NjksImV4cCI6MTUyMzQxNjYyOX0.Tk91b6mvyjpKcldkic8DgXz0zsPFF nRgTgkgcAsa9cc"; 
Claims claims = Jwts.parser().setSigningKey("itcast").parseClaimsJws(compactJws).getBody( ); System.out.println("id:"+claims.getId()); System.out.println("subject:"+claims.getSubject()); 
SimpleDateFormat sdf=new SimpleDateFormat("yyyy‐MM‐dd hh:mm:ss"); System.out.println("签发时间:"+sdf.format(claims.getIssuedAt())); System.out.println("过期时 间:"+sdf.format(claims.getExpiration())); System.out.println("当前时间:"+sdf.format(new Date()) ); } }

测试运行,当未过期时可以正常读取,当过期时会引发 io.jsonwebtoken.ExpiredJwtException异常。
在这里插入图片描述
4.2.4 自定义claims
我们刚才的例子只是存储了id和subject两个信息,如果你想存储更多的信息(例如角 色)可以定义自定义claims 创建CreateJwtTest3

public class CreateJwtTest3 { 
public static void main(String[] args) { 
//为了方便测试,我们将过期时间设置为1分钟 
long now = System.currentTimeMillis();//当前时间 
long exp = now + 1000*60;//过期时间为1分钟 
JwtBuilder builder= Jwts.builder().setId("888") .setSubject("小白") .setIssuedAt(new Date()) .signWith(SignatureAlgorithm.HS256,"itcast") .setExpiration(new Date(exp)) .claim("roles","admin") .claim("logo","logo.png"); 
System.out.println( builder.compact() ); } }

修改ParseJwtTest

public class ParseJwtTest { 
public static void main(String[] args) { 
String compactJws="eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4ODgiLCJzdWIiOiLlsI_nmb0iLCJp YXQiOjE1MjM0MTczMjMsImV4cCI6MTUyMzQxNzM4Mywicm9sZXMiOiJhZG1pbiIsImxvZ28iO iJsb2dvLnBuZyJ9.b11p4g4rE94rqFhcfzdJTPCORikqP_1zJ1MP8KihYTQ"; 
Claims claims = Jwts.parser().setSigningKey("itcast").parseClaimsJws(compactJws).getBody( ); System.out.println("id:"+claims.getId()); System.out.println("subject:"+claims.getSubject()); System.out.println("roles:"+claims.get("roles")); System.out.println("logo:"+claims.get("logo")); 
SimpleDateFormat sdf=new SimpleDateFormat("yyyy‐MM‐dd hh:mm:ss"); System.out.println("签发时间:"+sdf.format(claims.getIssuedAt())); System.out.println("过期时 间:"+sdf.format(claims.getExpiration())); System.out.println("当前时间:"+sdf.format(new Date()) ); } }

5 十次方微服务鉴权

5.1 JWT工具类编写

(1)tensquare_common工程引入依赖(考虑到工具类的通用性)

<dependency> 
<groupId>io.jsonwebtoken</groupId> 
<artifactId>jjwt</artifactId> 
<version>0.6.0</version> 
</dependency>

(2)修改tensquare_common工程,创建util.JwtUtil

@ConfigurationProperties("jwt.config") 
public class JwtUtil { 
private String key ; 
private long ttl ;//一个小时 
public String getKey() { return key; }
public void setKey(String key) { this.key = key; }
public long getTtl() { return ttl; }
public void setTtl(long ttl) { this.ttl = ttl; }
/*** 生成JWT ** @param id * @param subject * @return */ 
public String createJWT(String id, String subject, String roles) { 
long nowMillis = System.currentTimeMillis(); 
Date now = new Date(nowMillis); 
JwtBuilder builder = Jwts.builder().setId(id) .setSubject(subject) .setIssuedAt(now) .signWith(SignatureAlgorithm.HS256, key).claim("roles", roles); 
if (ttl > 0) { builder.setExpiration( new Date( nowMillis + ttl));
}return builder.compact(); 
}
/*** 解析JWT * @param jwtStr * @return */ 
public Claims parseJWT(String jwtStr){ 
return Jwts.parser() .setSigningKey(key) .parseClaimsJws(jwtStr) .getBody(); } 
}

(3)修改tensquare_user工程的application.yml, 添加配置

jwt: config: key: itcast ttl: 360000

5.2 管理员登陆后台签发token

(1)配置bean .修改tensquare_user工程Application类

@Bean public JwtUtil jwtUtil(){ return new util.JwtUtil(); }

(2)修改AdminController的login方法

@Autowired private JwtUtil jwtUtil; 
/*** 用户登陆 * @param loginname * @param password * @return */ @RequestMapping(value="/login",method=RequestMethod.POST) 
public Result login(@RequestBody Map<String,String> loginMap){ 
Admin admin = adminService.findByLoginnameAndPassword(loginMap.get("loginname"), loginMap.get("password")); 
if(admin!=null){ //生成token 
String token = jwtUtil.createJWT(admin.getId(), admin.getLoginname(), "admin"); 
Map map=new HashMap(); 
map.put("token",token); 
map.put("name",admin.getLoginname());//登陆名 
return new Result(true,StatusCode.OK,"登陆成功",map); 
}else{
return new Result(false,StatusCode.LOGINERROR,"用户名或密码错 误"); 
} 
}

测试运行结果

{ 
"flag": true, 
"code": 20000, 
"message": "登陆成功", 
"data": { 
"token": "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI5ODQzMjc1MDc4ODI5MzgzNjgiLCJzdWIiOiJ4aWF vbWkiLCJpYXQiOjE1MjM1MjQxNTksInJvbGVzIjoiYWRtaW4iLCJleHAiOjE1MjM1MjQ1MTl9 ._YF3oftRNTbq9WCD8Jg1tqcez3cSWoQiDIxMuPmp73o", 
"name":"admin" 
} 
}

5.3 删除用户功能鉴权

需求:删除用户,必须拥有管理员权限,否则不能删除。
前后端约定:前端请求微服务时需要添加头信息Authorization ,内容为Bearer+空格 +token
(1)修改UserController的findAll方法 ,判断请求中的头信息,提取token并证权 限。

@Autowired 
private HttpServletRequest request; 
/*** 删除 * @param id */ @RequestMapping(value="/{id}",method= RequestMethod.DELETE) 
public Result delete(@PathVariable String id ){ 
String authHeader = request.getHeader("Authorization");//获取头信 息 if(authHeader==null){ 
return new Result(false,StatusCode.ACCESSERROR,"权限不足"); }
if(!authHeader.startsWith("Bearer ")){ return new Result(false,StatusCode.ACCESSERROR,"权限不足"); }
String token=authHeader.substring(7);//提取token 
Claims claims = jwtUtil.parseJWT(token); 
if(claims==null){ return new Result(false,StatusCode.ACCESSERROR,"权限不足"); }
if(!"admin".equals(claims.get("roles"))){ return new Result(false,StatusCode.ACCESSERROR,"权限不足"); }
userService.deleteById(id); 
return new Result(true,StatusCode.OK,"删除成功"); 
}

5.4 使用拦截器方式实现token鉴权

如果我们每个方法都去写一段代码,冗余度太高,不利于维护,那如何做使我们的代码 看起来更清爽呢?我们可以将这段代码放入拦截器去实现
5.4.1 添加拦截器
Spring为我们提供了 org.springframework.web.servlet.handler.HandlerInterceptorAdapter这个适配器, 继承此类,可以非常方便的实现自己的拦截器。他有三个方法: 分别实现预处理、后处理(调用了Service并返回ModelAndView,但未进行页面渲 染)、返回处理(已经渲染了页面) 在

preHandle中,可以进行编码、安全控制等处理; 在postHandle中,有机会修改ModelAndView; 在afterCompletion中,可以根据ex是否为null判断是否发生了异常,进行日志记录

(1)创建拦截器类。创建 com.tensquare.user.filter.JwtFilter

@Component 
public class JwtFilter extends HandlerInterceptorAdapter { 
@Autowired 
private JwtUtil jwtUtil; 
@Override 
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("经过了拦截器"); return true; } }

(2)配置拦截器类,创建com.tensquare.user.ApplicationConfig

@Configuration 
public class ApplicationConfig extends WebMvcConfigurationSupport { @Autowired private JwtFilter jwtFilter; 
@Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(jwtFilter). addPathPatterns("/**"). excludePathPatterns("/**/login"); } }

5.4.2 拦截器验证token
(1)修改拦截器类 JwtFilter

@Component 
public class JwtFilter extends HandlerInterceptorAdapter { 
@Autowired 
private JwtUtil jwtUtil; 
@Override 
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 
System.out.println("经过了拦截器"); 
final String authHeader = request.getHeader("Authorization"); 
if (authHeader != null && authHeader.startsWith("Bearer ")) { 
final String token = authHeader.substring(7); // The part after "Bearer " Claims claims = jwtUtil.parseJWT(token); 
if (claims != null) { if("admin".equals(claims.get("roles"))){
//如果是管理员 
request.setAttribute("admin_claims", claims); }if("user".equals(claims.get("roles"))){
//如果是用户 
request.setAttribute("user_claims", claims); 
} 
} 
}return true; 
} 
}

(2)修改UserController的delete方法

/*** 删除 * @param id */ 
@RequestMapping(value="/{id}",method= RequestMethod.DELETE) 
public Result delete(@PathVariable String id ){ 
Claims claims=(Claims) request.getAttribute("admin_claims"); 
if(claims==null){ return new Result(true,StatusCode.ACCESSRROR,"无权访问"); }
userService.deleteById(id); 
return new Result(true,StatusCode.OK,"删除成功"); 
}

6 发布信息验证Token

6.1 用户登陆签发 JWT

(2)修改UserController,引入JwtUtil 修改login方法 ,返回token,昵称,头像等信 息

@Autowired 
private JwtUtil jwtUtil; 
/*** 用户登陆 * @param mobile * @param password * @return */ @RequestMapping(value="/login",method=RequestMethod.POST) public Result login(@RequestBody Map<String,String> loginMap){ 
User user = userService.findByMobileAndPassword(loginMap.get("mobile"),loginMap.get(" password")); 
if(user!=null){ 
String token = jwtUtil.createJWT(user.getId(), user.getNickname(), "user"); Map map=new HashMap(); 
map.put("token",token); 
map.put("name",user.getNickname());//昵称 map.put("avatar",user.getAvatar());//头像 return new Result(true,StatusCode.OK,"登陆成功",map); }else{return new Result(false,StatusCode.LOGINERROR,"用户名或密码错 误"); 
} 
}

(4)测试运行 http://localhost:9008/user/login (POST) ,结果为如下形式

{ 
"flag": true, 
"code": 20000, 
"message": "登陆成功", 
"data": { "token": "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI5ODM5ODc0ODk1MDcyNTAxNzYiLCJpYXQiOjE1MjM 1MDIzMDEsInJvbGVzIjoidXNlciIsImV4cCI6MTUyMzUwMjY2MX0.QH‐ WMRgIAxHDcYReH7patg7qkcjc4ZuyDbHaIah‐spQ" },"name":"小雅", "avatar":"......." }

6.2 发布问题

(1)修改tensquare_qa工程的QaApplication,增加bean

@Bean public JwtUtil jwtUtil(){ return new util.JwtUtil(); }

(2)tensquare_qa工程配置文件application.yml增加配置:

jwt:config: key: itcast

(3)增加拦截器类 (参考上面的拦截器代码)
(4)增加配置类ApplicationConfig (参考上面的配置类代码)
(5)修改ProblemController的add方法‘

@Autowired 
private HttpServletRequest request; 
/*** 发布问题 * @param problem */ 
@RequestMapping(method=RequestMethod.POST) 
public Result add(@RequestBody Problem problem ){ 
Claims claims=(Claims)request.getAttribute("user_claims"); 
if(claims==null){ 
return new Result(false,StatusCode.ACCESSERROR,"无权访问"); }
problem.setUserid(claims.getId()); 
problemService.add(problem); 
return new Result(true,StatusCode.OK,"增加成功"); 
}

6.3 回答问题

学员实现,步骤略

6.4 发吐槽

学员实现,步骤略

6.5 发文章

学员实现,步骤略

查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. Failed to introspect Class [org...DiscoveryClientOptionalArgsConfiguration from ClassLoader ...

    在启动zuul工程时候报的问题 报错原文:java.lang.IllegalStateException: Failed to introspect Class [org.springframework.cloud.netflix.eureka.config.DiscoveryClientOptionalArgsConfiguration] from ClassLoader [sun.misc.Launcher$AppClassLoader@18b4aac2]at org.s…...

    2024/4/29 5:44:14
  2. 视频去抖动算法原理及代码详解

    1. 背景点播、直播行业的蓬勃发展,使用户生产视频(UGC)逐渐替代了专家生产和平台生产的方式,成为了主流。由于广大用户不可能全都具备专业素质和专业器材,其产出的视频往往质量较差,最明显的特征就是存在抖动。减少视频抖动有很多方法,包括使用专业摄影辅助器材,如三脚架…...

    2024/5/6 5:25:15
  3. CSS选择器/复合选择器、关系选择器

    CSS选择器/复合选择器、关系选择器<今日分学习清单----两种复合选择器,以及三代关系选择器!!!>Target 1:复合选择器 交集选择器作用:同时复合多个条件的单个选择器元素 语法:选择器1 选择器2 选择器3 … 选择器n { } 注意:交集选择器中若有元素选择器(这里简单…...

    2024/5/4 14:56:42
  4. 顶点片元Shader简单实例之海浪

    效果步骤新建一个unity3d项目 创建res文件夹存放贴图和shader以及对应材质,贴图可自行在网络上查找,shader创建如下图所示(shader的源代码往下看,有详细注释),创建完shader之后,鼠标右击shader创建对应材质(create->material)然后将贴图拖到材质中然后在场景中创建一…...

    2024/5/8 21:25:59
  5. poi导出excel时提示功能

    DVConstraint constraint = DVConstraint.createCustomFormulaConstraint("BB1"); /* 四个参数分别是:起始行、终止行、起始列、终止列 */ CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol); /* 数据有效性对象 */ HS…...

    2024/4/30 14:23:29
  6. 5-1-1 Master research tools

    OResearch: Master pipeline research tools and article classificationKRDocument management:zotero...

    2024/4/19 22:05:29
  7. Promise的使用

    new Promise(resolve => {setTimeout(() => {resolve(hello)}, 2000)}).then(val => {console.log(val) // 参数val = helloreturn new Promise(resolve => {setTimeout(() => {resolve(world)}, 2000)})}).then(val => {console.log(val) // 参数val = wor…...

    2024/5/8 20:54:43
  8. Java学到什么程度才能找到工作?从国内各阶层互联网公司分析

    Java学到什么程度才能找到工作?从国内各阶层互联网公司分析 刚开始学习Java的小伙伴,尤其是那种又没钱又没有背景的,刚开始学习Java都关心这么一个问题:到底把Java学到何种程度才能找到第一份工作呢? 每个人都很现实,目标都是相当的一致,都是为了能拿到像别人高薪的工作…...

    2024/5/1 5:47:48
  9. Unity Editor 基础篇(十三):更改Project资源的Inspector显示

    代码参自:http://anchan828.github.io/editor-manual/web/customeditor.html之前已经讨论过场景中物体在Inspector面板的显示的更改,今天讨论一下Project面板中资源在Inspector面板的显示。例如,点击Project里一个C#脚本,在Inspector面板就会出现脚本内容的预览,但是项目中…...

    2024/5/4 16:50:46
  10. 类加载机制加载完成后得到的是什么?重复new同一个类的对象会加载多少次?

    类加载完成之后得到的是一个类对象。类名.class对象。重复new同一个类的对象也是只会加载一次这个类,只是会多次执行实例化的步骤。...

    2024/5/8 13:22:24
  11. LayUI数据表格 表单参数、可编辑自定义单元格、图片、操作

    前言 在使用layUI的数据表格时,常用到的一些渲染和操作一、数据表格参数及使用 1.1 图片 templet 参数注意:a标签也差不多,就是 href=’’/xxx.html/id={{d.id}}"// {{d.img}} 后台返的图片地址 "d"在layui中特指data,id为templ <script type="text…...

    2024/4/28 18:32:23
  12. 手机端设计规范(750*1334)

    以750*1334为例 统一字体:苹方一、文本1.主题类:展示标题:小字号 36 加粗 行距50 大字号 40 加粗行距58主标题:大字号 32 加粗 小字号28 中等副标题:大字号30 加粗 小字号 24 中等 2.文本类:主文本:字号36 中等 行距58辅文本:字号60 行距48 中等次要文本:…...

    2024/4/15 20:48:25
  13. GIS几何查询

    GIS几何查询有点 线 面 的方式,主要用于获取目标内的某些信息。<body onload="init()"><div id="toolbar"><input type="button" class="btn" value="点" onclick="drawGeometry3()" /><…...

    2024/5/8 15:20:27
  14. mysql 实现字符串的拼接

    在Mysql 数据库中存在两种字符串连接操作.具体操作如下一. 语法:1. CONCAT(string1,string2,…) 说明 : string1,string2代表字符串,concat函数在连接字符串的时候,只要其中一个是NULL,那么将返回NULL例1:例2:2. CONCAT_WS(separator,str1,str2,...)说明 : string1,string2代…...

    2024/4/15 20:48:23
  15. PHP大数据导出csv优化,导出出现504处理方式

    $title = [粉丝编号,用户名,联系电话,状态,创建时间,订单数量]; set_time_limit(0); header(Pragma:public); header(Expires:0); header(Cache-Control:must-revalidate,post-check=0,pre-check=0); header(Content-Type:application/force-download); header(Con…...

    2024/4/15 20:48:22
  16. Tomcat应用服务器的简单实现

    Tomcat应用服务器的简单实现 简单来说就是实现一个基于TCP的HTTP服务器,可以完成静态资源和动态资源的访问。 Tomcat的职责: 1)正确监听TCP端口并处理客户端发起的TCP连接请求。 2)在已经建立TCP连接的基础上,可以正确的从TCP连接中读取数据。 3)可以按照HTTP协议,解析数…...

    2024/4/29 9:14:40
  17. ai制作PSG图形

    ctrl+J 链接两个端点 ctrl+: 隐藏参考线shift+X 填充描边转换...

    2024/5/4 1:35:27
  18. Codeforces Beta Round #1B Spreadsheets

    题目描述: 大家都见过的excel列表或者说二维数组,对于行和列的描述我们给出以下两种方式: 1.RxCy型,R代表row,C代表column,x和y分别表示两个整数。 2.Mx型,M表示一个由大写字母表示的字符串,A规定为1,Z规定为26,而AA规定为27,AZ规定为52,依次类推,代表column。x表…...

    2024/4/25 4:49:28
  19. jupyter-notebook使用指定虚拟环境(实验过得)

    https://blog.csdn.net/weixin_40506067/article/details/106903411...

    2024/5/5 11:57:03
  20. ibm mq简单入门

    在项目中,我们可能会用到mq消息传递。所以这里咱么就来了解一下IBM MQ。需要知道几个名字。队列管理器队列通道需要安装IBM WebSphere MQ。安装完启动。如下图所示安装ibm mq 完成后,查看帮助内容。创建好后,我们通过spring jms 去跟mq...

    2024/4/21 5:30:06

最新文章

  1. 【管理咨询宝藏95】SRM采购平台建设内部培训方案

    本报告首发于公号“管理咨询宝藏”&#xff0c;如需阅读完整版报告内容&#xff0c;请查阅公号“管理咨询宝藏”。 【管理咨询宝藏95】SRM采购平台建设内部培训方案 【格式】PDF版本 【关键词】SRM采购、制造型企业转型、数字化转型 【核心观点】 - 重点是建设一个适应战略采…...

    2024/5/8 22:52:06
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/5/7 10:36:02
  3. C++ //练习 11.14 扩展你在11.2.1节练习(第378页)中编写的孩子姓到名的map,添加一个pair的vector,保存孩子的名和生日。

    C Primer&#xff08;第5版&#xff09; 练习 11.14 练习 11.14 扩展你在11.2.1节练习&#xff08;第378页&#xff09;中编写的孩子姓到名的map&#xff0c;添加一个pair的vector&#xff0c;保存孩子的名和生日。 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#x…...

    2024/5/5 8:38:52
  4. HTML——4.表格、列表、区块

    一、表格 HTML 表格是用于展示结构化数据的重要元素&#xff0c;它允许将数据以行和列的形式组织和显示。 基本结构和常见元素&#xff1a; 1. <table> 元素 <table> 元素是 HTML 表格的根元素&#xff0c;它用于定义整个表格的开始和结束。 2. <thead>、…...

    2024/5/8 7:35:57
  5. 416. 分割等和子集问题(动态规划)

    题目 题解 class Solution:def canPartition(self, nums: List[int]) -> bool:# badcaseif not nums:return True# 不能被2整除if sum(nums) % 2 ! 0:return False# 状态定义&#xff1a;dp[i][j]表示当背包容量为j&#xff0c;用前i个物品是否正好可以将背包填满&#xff…...

    2024/5/8 19:32:33
  6. 【Java】ExcelWriter自适应宽度工具类(支持中文)

    工具类 import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet;/*** Excel工具类** author xiaoming* date 2023/11/17 10:40*/ public class ExcelUti…...

    2024/5/7 22:31:36
  7. Spring cloud负载均衡@LoadBalanced LoadBalancerClient

    LoadBalance vs Ribbon 由于Spring cloud2020之后移除了Ribbon&#xff0c;直接使用Spring Cloud LoadBalancer作为客户端负载均衡组件&#xff0c;我们讨论Spring负载均衡以Spring Cloud2020之后版本为主&#xff0c;学习Spring Cloud LoadBalance&#xff0c;暂不讨论Ribbon…...

    2024/5/8 1:37:40
  8. TSINGSEE青犀AI智能分析+视频监控工业园区周界安全防范方案

    一、背景需求分析 在工业产业园、化工园或生产制造园区中&#xff0c;周界防范意义重大&#xff0c;对园区的安全起到重要的作用。常规的安防方式是采用人员巡查&#xff0c;人力投入成本大而且效率低。周界一旦被破坏或入侵&#xff0c;会影响园区人员和资产安全&#xff0c;…...

    2024/5/8 20:33:13
  9. VB.net WebBrowser网页元素抓取分析方法

    在用WebBrowser编程实现网页操作自动化时&#xff0c;常要分析网页Html&#xff0c;例如网页在加载数据时&#xff0c;常会显示“系统处理中&#xff0c;请稍候..”&#xff0c;我们需要在数据加载完成后才能继续下一步操作&#xff0c;如何抓取这个信息的网页html元素变化&…...

    2024/5/8 1:37:39
  10. 【Objective-C】Objective-C汇总

    方法定义 参考&#xff1a;https://www.yiibai.com/objective_c/objective_c_functions.html Objective-C编程语言中方法定义的一般形式如下 - (return_type) method_name:( argumentType1 )argumentName1 joiningArgument2:( argumentType2 )argumentName2 ... joiningArgu…...

    2024/5/7 16:57:02
  11. 【洛谷算法题】P5713-洛谷团队系统【入门2分支结构】

    &#x1f468;‍&#x1f4bb;博客主页&#xff1a;花无缺 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 花无缺 原创 收录于专栏 【洛谷算法题】 文章目录 【洛谷算法题】P5713-洛谷团队系统【入门2分支结构】&#x1f30f;题目描述&#x1f30f;输入格…...

    2024/5/7 14:58:59
  12. 【ES6.0】- 扩展运算符(...)

    【ES6.0】- 扩展运算符... 文章目录 【ES6.0】- 扩展运算符...一、概述二、拷贝数组对象三、合并操作四、参数传递五、数组去重六、字符串转字符数组七、NodeList转数组八、解构变量九、打印日志十、总结 一、概述 **扩展运算符(...)**允许一个表达式在期望多个参数&#xff0…...

    2024/5/8 20:58:56
  13. 摩根看好的前智能硬件头部品牌双11交易数据极度异常!——是模式创新还是饮鸩止渴?

    文 | 螳螂观察 作者 | 李燃 双11狂欢已落下帷幕&#xff0c;各大品牌纷纷晒出优异的成绩单&#xff0c;摩根士丹利投资的智能硬件头部品牌凯迪仕也不例外。然而有爆料称&#xff0c;在自媒体平台发布霸榜各大榜单喜讯的凯迪仕智能锁&#xff0c;多个平台数据都表现出极度异常…...

    2024/5/7 21:15:55
  14. Go语言常用命令详解(二)

    文章目录 前言常用命令go bug示例参数说明 go doc示例参数说明 go env示例 go fix示例 go fmt示例 go generate示例 总结写在最后 前言 接着上一篇继续介绍Go语言的常用命令 常用命令 以下是一些常用的Go命令&#xff0c;这些命令可以帮助您在Go开发中进行编译、测试、运行和…...

    2024/5/8 1:37:35
  15. 用欧拉路径判断图同构推出reverse合法性:1116T4

    http://cplusoj.com/d/senior/p/SS231116D 假设我们要把 a a a 变成 b b b&#xff0c;我们在 a i a_i ai​ 和 a i 1 a_{i1} ai1​ 之间连边&#xff0c; b b b 同理&#xff0c;则 a a a 能变成 b b b 的充要条件是两图 A , B A,B A,B 同构。 必要性显然&#xff0…...

    2024/5/7 16:05:05
  16. 【NGINX--1】基础知识

    1、在 Debian/Ubuntu 上安装 NGINX 在 Debian 或 Ubuntu 机器上安装 NGINX 开源版。 更新已配置源的软件包信息&#xff0c;并安装一些有助于配置官方 NGINX 软件包仓库的软件包&#xff1a; apt-get update apt install -y curl gnupg2 ca-certificates lsb-release debian-…...

    2024/5/8 18:06:50
  17. Hive默认分割符、存储格式与数据压缩

    目录 1、Hive默认分割符2、Hive存储格式3、Hive数据压缩 1、Hive默认分割符 Hive创建表时指定的行受限&#xff08;ROW FORMAT&#xff09;配置标准HQL为&#xff1a; ... ROW FORMAT DELIMITED FIELDS TERMINATED BY \u0001 COLLECTION ITEMS TERMINATED BY , MAP KEYS TERMI…...

    2024/5/8 1:37:32
  18. 【论文阅读】MAG:一种用于航天器遥测数据中有效异常检测的新方法

    文章目录 摘要1 引言2 问题描述3 拟议框架4 所提出方法的细节A.数据预处理B.变量相关分析C.MAG模型D.异常分数 5 实验A.数据集和性能指标B.实验设置与平台C.结果和比较 6 结论 摘要 异常检测是保证航天器稳定性的关键。在航天器运行过程中&#xff0c;传感器和控制器产生大量周…...

    2024/5/7 16:05:05
  19. --max-old-space-size=8192报错

    vue项目运行时&#xff0c;如果经常运行慢&#xff0c;崩溃停止服务&#xff0c;报如下错误 FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory 因为在 Node 中&#xff0c;通过JavaScript使用内存时只能使用部分内存&#xff08;64位系统&…...

    2024/5/8 1:37:31
  20. 基于深度学习的恶意软件检测

    恶意软件是指恶意软件犯罪者用来感染个人计算机或整个组织的网络的软件。 它利用目标系统漏洞&#xff0c;例如可以被劫持的合法软件&#xff08;例如浏览器或 Web 应用程序插件&#xff09;中的错误。 恶意软件渗透可能会造成灾难性的后果&#xff0c;包括数据被盗、勒索或网…...

    2024/5/8 1:37:31
  21. JS原型对象prototype

    让我简单的为大家介绍一下原型对象prototype吧&#xff01; 使用原型实现方法共享 1.构造函数通过原型分配的函数是所有对象所 共享的。 2.JavaScript 规定&#xff0c;每一个构造函数都有一个 prototype 属性&#xff0c;指向另一个对象&#xff0c;所以我们也称为原型对象…...

    2024/5/8 12:44:41
  22. C++中只能有一个实例的单例类

    C中只能有一个实例的单例类 前面讨论的 President 类很不错&#xff0c;但存在一个缺陷&#xff1a;无法禁止通过实例化多个对象来创建多名总统&#xff1a; President One, Two, Three; 由于复制构造函数是私有的&#xff0c;其中每个对象都是不可复制的&#xff0c;但您的目…...

    2024/5/8 9:51:44
  23. python django 小程序图书借阅源码

    开发工具&#xff1a; PyCharm&#xff0c;mysql5.7&#xff0c;微信开发者工具 技术说明&#xff1a; python django html 小程序 功能介绍&#xff1a; 用户端&#xff1a; 登录注册&#xff08;含授权登录&#xff09; 首页显示搜索图书&#xff0c;轮播图&#xff0…...

    2024/5/8 1:37:29
  24. 电子学会C/C++编程等级考试2022年03月(一级)真题解析

    C/C++等级考试(1~8级)全部真题・点这里 第1题:双精度浮点数的输入输出 输入一个双精度浮点数,保留8位小数,输出这个浮点数。 时间限制:1000 内存限制:65536输入 只有一行,一个双精度浮点数。输出 一行,保留8位小数的浮点数。样例输入 3.1415926535798932样例输出 3.1…...

    2024/5/7 17:09:45
  25. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  26. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  27. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  28. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  29. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  30. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  31. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  32. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  33. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  34. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  35. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  36. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  37. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  38. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  39. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  40. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  41. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  42. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  43. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  44. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57