项目2---十次方项目开发---后台--鉴权和JWT---06

第一步:引入springSecurity。

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

默认的配置是拦截所有的路径。

第二步:写配置类

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    /**
     * authorizeRequests:所有security全注解配置实现的开端。表示开始说明需要的权限
     * 需要的权限分两部分,第一部分是拦截的路径,第二部分访问路径需要的权限
     * antMatchers:表示拦截路径,permitAll表示任何权限都可以使用,直接放行所有
     * anyRequest():任何的请求,authenticated():认证后才能访问
     * .and().csrf().disable():固定写法,表示使csrf拦截失效
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/**").permitAll()
                .anyRequest().authenticated()
                .and().csrf().disable();
    }
}

这个适配器实现了一些空的方法。这段可以作为模板贴上去的。

-------------------------------------------------------------------01-----------------------------------------02----------------03-----------------------------------

springboot是把web.xml拿掉的。

web.xml是初始化的,现在这个替代了。

---------------------------------------------------------------------------04-----------------------------------------------------------------------

加密的网址:https://www.jianshu.com/p/89c4c476e189

引入加密算法:

第一步:

@SpringBootApplication
public class UserApplication {

	public static void main(String[] args) {
		SpringApplication.run(UserApplication.class, args);
	}

	@Bean
	public IdWorker idWorkker(){
		return new IdWorker(1, 1);
	}

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

第二步:注入和使用,对密码进行加密存入到数据库。

public void add(Admin admin) {
		admin.setId( idWorker.nextId()+"" ); //雪花分布式ID生成器
		admin.setPassword(encoder.encode(admin.getPassword()));//密码加密
		adminDao.save(admin);
	}

第三步:测试

---------------------------------------------------------------------------05-----------------------------------------------------------------------

写登陆:

第一步:

	public Admin login(Admin admin) {
		//先根据用户名查询对象.
		Admin admin_login = adminDao.findByLoginname(admin.getLoginname());
		//拿数据库中的密码和用户输入的密码匹配是否相同
		if(admin_login!=null&&encoder.matches(admin.getPassword(),admin_login.getPassword())){
			//保证数据库中的密码和用户输入的密码是一致的
			//登录成功
			return admin_login;
		}
		//登录失败
		return null;
	}

知识点:

@RequestBody:可以转为对象也可以转为map。

第二步:写controller

-----------------------------------------------------------------------------06----------------------------------------------------------------------------

用户的注册登陆的改造:

第一步:加密关键代码

/**
	 * 增加
	 * @param user
	 */
	public void add(User user) {
		user.setId( idWorker.nextId()+"" );
		//密码加密
		user.setPassword(encoder.encode(user.getPassword()));
		user.setFollowcount(0);//关注数
		user.setFanscount(0);//粉丝数
		user.setOnline(0L);//在线时长//
		user.setRegdate(new Date());//注册日期
		user.setUpdatedate(new Date());//更新日期
		user.setLastdate(new Date());//最后登陆日期
		userDao.save(user);
	}

第二步:登陆关键代码

public User login(String mobile,String password) {
		User user = userDao.findByMobile(mobile);
		if(user!=null && encoder.matches(password,user.getPassword())){
			return user;
		}
		return null;
	}

---------------------------------------------------------------------------07-----------------------------------------------------------------------

常见的认证机制:

1.每次都带上用户名和密码,无状态的。

2.CooKie Auth:登陆的信息在浏览器存在cookie,服务器存在session中。安卓ios什么的不方便。手机端现在越来越流行了。

3.OAuth:

4.Token Auth:

服务端是不存的用JWT算法。到时候我解密就可以了。

这个token的生成策略我们用的是JWT。

---------------------------------------------------------------------------08-----------------------------------------------------------------------

token的优点:

---------------------------------------------------------------------------09-----------------------------------------------------------------------

JWT生成tokrn的规则:

头部,载荷,签名。

头部:

载荷:

签名:对头部和载荷进行加密。

最后一点JWT是后台签发的。三部分组成。

---------------------------------------------------------------------------10-----------------------------------------------------------------------

JJWT:

第一步:导入坐标在common模块注意是在common模块里面。

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

第二步:

 List<Object> roles=new ArrayList<>();
        roles.add("role1");
        roles.add("role2");
        JwtBuilder jwtBuilder = Jwts.builder()
                //用户的id用户名
                .setId("666") .setSubject("小马")
                .setIssuedAt(new Date())//何时登陆的
                .signWith(SignatureAlgorithm.HS256,"wmlw")//头部信息  后面的是加的盐
                .setExpiration(new Date(new Date().getTime()+60000))
                .claim("roles",roles);
        System.out.println(jwtBuilder.compact());

这个set是按照这个标准set的:

----------------------------------------------------------------------------------11---------------------------------------------------------------------------------

解析JWT:

public static void main(String[] args) {
        //Claims里面就是key和value
        Claims claims = Jwts.parser().setSigningKey("wmlw")
                .parseClaimsJws("eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI2NjYiLCJzdWIiOiLlsI_pqawiLCJpYXQiOjE1ODAzNjA5NzksImV4cCI6MTU4MDM2MTAzOSwicm9sZXNBZGQiOlsicm9sZTEiLCJyb2xlMiJdfQ.Lx9C8olEcY29NHSx90Q0aifA1JjwzwyyKpWkadzk2eI")
                .getBody();
        System.out.println("用户id"+claims.getId());
        System.out.println("用户名"+claims.getSubject());
        System.out.println("登录时间"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(claims.getIssuedAt()));
        System.out.println("过期时间"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(claims.getExpiration()));
        System.out.println("角色"+claims.get("rolesAdd"));
    }

---------------------------------------------------------------------------12-----------------------------------------------------------------------

token的过期时间:

同上。

---------------------------------------------------------------------------13-----------------------------------------------------------------------

添加自定义的键值对:

---------------------------------------------------------------------------14-----------------------------------------------------------------------

token工具类:

第一步:拷贝JwtUtils:

注意下这个微服务的配置文件是引用它的微服务的配置文件读取的。没毛病。

第二步:

必传的信息:id,

---------------------------------------------------------------------------15-----------------------------------------------------------------------

admin登陆生成token:

第一步:我们写加盐的yml注意在哪个模块里面。

第二步:在启动类加Jwt工具。

第三步:写代码

用户 角色 权限 都是多对多

    @PostMapping("/login")
    public Result login(@RequestBody Admin admin) {
        Admin adminLogin = adminService.login(admin);
        if (adminLogin == null) {
            return new Result(false, StatusCode.ERROR, "登录失败");
        }
        //是的前后端可以通话的操作。采用JWT操作
        //生成令牌
//        List<Object> roles = new ArrayList<>();
//		roles.add("role1");
//		roles.add("role2");
        String token = jwtUtil.createJWT(adminLogin.getId(), adminLogin.getLoginname(), "admin");
        Map<String, Object> map = new HashMap<>();
        map.put("token", token);
        map.put("role", "admin");
        return new Result(true, StatusCode.OK, "登录成功", map);
//        return new Result(true, StatusCode.OK, "登录成功", "登陆凭证");

    }

测试登陆:

---------------------------------------------------------------------------16-----------------------------------------------------------------------

我们假设一个场景:删除的功能。我们要把token放在请求头里面。

第一步:request是一次请求,拿到request才能拿到请求头。

测试:

先登陆:

请求:

--------------------------------------------------------------------------17----------18-------------------------------------------------------------

用拦截器写:

其实也可以用springSecurity。

jdk1.8的好处:

第一步写拦截器:

拦截器都放行,不管是什么,在请求的request写入角色。

第二步:写配置configuration

相当于配置xml。

-----------------------------------------------------------------------19------20---------------------------------------------------------------- 

拦截器的验证测试:

第一步:改造userService

   public void deleteById(String id) {
//        String header = request.getHeader("Authorization");
//        if (header == null || header.equals("")) {
//            throw new RuntimeException("权限不足!");
//        }
//        if (!header.startsWith("Bearer ")) {
//            throw new RuntimeException("权限不足");
//        }
//        //得到token
//        String token = header.substring(7);
//        try {
//            Claims claims = jwtUtil.parseJWT(token);
//            String roles = (String) claims.get("roles");
//            if (roles == null && !"admin".equals(roles)) {
//                throw new RuntimeException("权限不足");
//            }
//        } catch (Exception e) {
//            throw new RuntimeException("权限不足");
//        }
        String token=(String)request.getAttribute("claims_admin");
        if(token==null || "".equals(token)){
            throw new RuntimeException("权限不足");
        }
        userDao.deleteById(id);
    }

测试:略。

--------------------------------------------------21---------------------------------------------

问答的token问题。

登陆才能问问题。

第一步:在UserService。

	@PostMapping("/login")
	public Result login(@RequestBody User user){
		user=userService.login(user.getMobile(),user.getPassword());
		if(user==null){
			return new Result(false,StatusCode.ERROR,"登录失败");
		}
		String token = jwtUtil.createJWT(user.getId(), user.getMobile(), "user");
		Map<String,Object> map =new HashMap<>();
		map.put("token",token);
		map.put("roles","user");
		return new Result(true,StatusCode.OK,"登录成功",map);
//		return new Result(true,StatusCode.OK,"登录成功","登陆成功");
	}

第二步:在问答里面验证

yml导入配置:

第三步:将过滤器导入

第四步:

/**
	 * 增加
	 * @param problem
	 */
	@RequestMapping(method=RequestMethod.POST)
	public Result add(@RequestBody Problem problem  ){
		String token=(String)request.getAttribute("claims_user");
		if(token ==null || "".equals(token)){
			return new Result(false,StatusCode.ACCESSERROR,"权限不足");
		}
		problemService.add(problem);
		return new Result(true,StatusCode.OK,"增加成功");
	}

--------------------------------------------------22---------------------------------------------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值