Почему мой код не дает jwtToken в результате почтальону с зарегистрированным пользователем - PullRequest
0 голосов
/ 18 января 2020

Я создаю простое приложение с творогом, используя весеннюю загрузку с jwt.when, когда я регистрирую пользователя с помощью почтальона ContentType / json, когда я отправляю все детали, я получаю ответы на все детали пользователя с кодом 201, но token = null я получаю. здесь я добавил фильтр jwt и файл контроллера пользователя, пожалуйста, проверьте и помогите мне, где я пропускаю код.

Вот мой код

JwtTokenProvider

@Component
public class JwtTokenProvider {

    @Value("${app.jwt.secret}")
    private String jwtSecret;

    @Value("${app.jwt.token.prefix}")
    private String jwtTokenPrefix;

    @Value("${app.jwt.header.string}")
    private String jwtHeaderString;

    @Value("${app.jwt.expiration-in-ms}")
    private Long jwtExpirationInMs;

    @SuppressWarnings("deprecation")
    public String generateToken(Authentication auth){
        String authorities = auth.getAuthorities().stream()
                .map(GrantedAuthority::getAuthority)
                .collect(Collectors.joining());

        return Jwts.builder().setSubject(auth.getName())
                .claim("roles", authorities)
                .setExpiration(new Date(System.currentTimeMillis() + jwtExpirationInMs))
                //.signWith(SignatureAlgorithm.ES512, jwtSecret).compact();
                .signWith(SignatureAlgorithm.ES512, jwtSecret.getBytes()).compact();

    }
    public Authentication getAuthentication(HttpServletRequest request){
        String token = resolveToken(request);
        if(token == null){
            return null;
        }
        Claims claims = Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(token).getBody();
        String username = claims.getSubject();
        final List<GrantedAuthority> authorities = Arrays.stream(claims.get("roles").toString().split(","))
                .map(role -> role.startsWith("ROLE_")?role:"ROLE_"+role)
                .map(SimpleGrantedAuthority::new)
                .collect(Collectors.toList());
        return username!= null ? new UsernamePasswordAuthenticationToken(username, null, authorities): null;
    }

    public boolean validateToken(HttpServletRequest request){
        String token = resolveToken(request);
        if(token == null){
            return false;
        }
        Claims claims = Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(token).getBody();
        if(claims.getExpiration().before(new Date())){
            return false;
        }
        return true;
    }

    private String resolveToken(HttpServletRequest req){
        //Bearer key...
        String bearerToken = req.getHeader(jwtHeaderString);
        if(bearerToken!=null && bearerToken.startsWith(jwtTokenPrefix)){
            return bearerToken.substring(7, bearerToken.length());
        }
        return null;
    }
}

authFilter

public class JWTAuthorizationFilter extends BasicAuthenticationFilter {

    private JwtTokenProvider jwtTokenProvider;

    public JWTAuthorizationFilter(AuthenticationManager authenticationManager,
                                  JwtTokenProvider tokenProvider) {
        super(authenticationManager);
        jwtTokenProvider = tokenProvider;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        Authentication authentication = jwtTokenProvider.getAuthentication(request);

        if(authentication !=null && jwtTokenProvider.validateToken(request)){
            SecurityContextHolder.getContext().setAuthentication(authentication);
        }
        chain.doFilter(request, response);
    }
}

userController

@RestController
public class UserController {

    @Autowired
    private JwtTokenProvider tokenProvider;

    @Autowired
    private UserService userService;

    @Autowired
    private ProductService productService;

    @Autowired
    private TransactionService transactionService;

    @PostMapping("/api/user/registration")
    public ResponseEntity<?> register(@RequestBody User user){
        if(userService.findByUsername(user.getUsername())!=null){
            return new ResponseEntity<>(HttpStatus.CONFLICT);
        }
        //default role.
        user.setRole(Role.USER);
        return new ResponseEntity<>(userService.saveUser(user), HttpStatus.CREATED);
    }

    @GetMapping("/api/user/login")
    public ResponseEntity<?> getUser(Principal principal){
        //principal = httpServletRequest.getUserPrincipal.
        if(principal == null){
            //logout will also use here so we should return ok http status.
            return ResponseEntity.ok(principal);
        }
        UsernamePasswordAuthenticationToken authenticationToken =
                (UsernamePasswordAuthenticationToken) principal;
        User user = userService.findByUsername(authenticationToken.getName());
        user.setToken(tokenProvider.generateToken(authenticationToken));

        return new ResponseEntity<>(user, HttpStatus.OK);
    }

Пожалуйста, помогите мне ..

Ответы [ 2 ]

0 голосов
/ 21 января 2020

Первое: получите вывод

Когда вы отправляете запрос POST на свой контроллер ("/ api / user / registration"), вы никогда не вызываете свой класс JwtTokenProvider. Поэтому токен никогда не генерируется.

Попробуйте выполнить следующее:

@PostMapping("/api/user/registration")
    public ResponseEntity<String> register(@RequestBody User user){
        if(userService.findByUsername(user.getUsername())!=null){
            return new ResponseEntity<>(HttpStatus.CONFLICT);
        }
        //default role.
        user.setRole(Role.USER);
        userService.saveUser(user);
// I am not sure if this is really correct, but it should do it... Otherwise, change this method.
        UsernamePasswordAuthenticationToken  auth = new UsernamePasswordAuthenticationToken(user.getUsername(), user.getRoles());
        String token = tokenProvider.generateToken(user);
        return ResponseEntity.ok(token);
    }

У вас должен быть выход.

Второй: используйте заголовок

Сначала у вас есть первый вывод с токеном, затем вы можете попробовать добавить токен в заголовок или куда угодно. Попробуйте, дайте мне знать.

0 голосов
/ 21 января 2020

Следует отметить несколько вещей.

  1. Вы пытаетесь увидеть токен JWT в теле ответа после вызова регистрации пользователя. Но метод генерации токена generateToken () вызывается в методе входа пользователя getUser (), а НЕ в методе регистрации пользователя register (). Таким образом, токен не будет сгенерирован при регистрации. Попробуйте войти в систему, токен будет сгенерирован.

  2. Вы передаете токен JWT в теле ответа. В идеале вы должны передать его в заголовке ответа «Авторизация». Вы можете использовать response.addHeader («Авторизация», токен).

...