Передача токена JWT и страницы JSP вместе в браузер, Springboot

#spring-boot

#весенняя загрузка

Вопрос:

Новичок здесь, я пытаюсь передать токен jwt в ответе, а также новую страницу jsp в браузер, но, похоже, не могу вернуть оба вместе из-за типа данных методов (это либо строка для передачи JSP, либо ResponseEntity<> для передачи токена). Как мне поступить с этим? есть ли альтернативный способ сделать это?

 public String createAuthenticationToken(@RequestParam("userName") String username, @RequestParam("Password") 
String password, Model model) throws Exception {
    
    authenticate(username, password);
    
    final UserDetails userDetails = userDetailsService.loadUserByUsername(username);
    final String token = jwtTokenUtil.generateToken(userDetails);
    
  

/ Это работает только в том случае, если тип методов — ResponseEntity , но мне также нужно передать это/
возвращает ResponseEntity.ok(новый JwtResponse(токен));

     model.addAttribute("UserName",username);
    model.addAttribute("token",token);
    return "homepage";
}
  

Ответ №1:

Итак, насколько я понимаю, вы пытаетесь проверить учетные данные пользователя как часть входа в систему, а затем показать домашнюю страницу, если учетные данные действительны. Кроме того, верните токен jwt.

Если это так, вы можете рассмотреть возможность возврата токена в защищенном файле cookie. Вот простой пример, который я придумал, чтобы показать, как это можно сделать с помощью фиктивного пользователя: https://github.com/nkumashi/springboot-webmvc-demo .

Суть проекта заключается в этом блоке кода в UserController.java класс:

 @RequestMapping(value = "/showUser", method = RequestMethod.POST)
public String showUser(@ModelAttribute("user") User user, Model model, HttpServletResponse response) {
    // extract user details and verify provided credentials
    // using a dummy user to keep things simple
    if(user.getFirstName().equals(dummyUser)) {
        // user login success
        Cookie cookie = new Cookie("token", "dummy-token");
        cookie.setMaxAge(COOKIE_EXPIRY_IN_SECONDS);
        cookie.setSecure(false);
        cookie.setHttpOnly(true);
        
        response.addCookie(cookie);
        model.addAttribute("User", user);
        // show the home page / user details
        return "showUser";
    } 
    // login failure
    model.addAttribute("message", "Invalid user!");
    return "error";
}
  

Комментарии:

1. Спасибо за ответ, не могли бы вы рассказать мне, как обрабатывать этот файл cookie со стороны клиента, который он получает? Я использую JSP и springboot.

2. Привет, Амаль! Ну, клиенту не нужно ничего явно делать. Браузер автоматически добавляет файлы cookie на стороне сервера в следующий раз, когда клиент отправляет запрос в тот же домен. У каждого файла cookie должна быть дата истечения срока действия. Браузер автоматически удаляет cookie по истечении срока действия. И, когда клиент делает следующий запрос без cookie, запрос завершается ошибкой с 401. Я думаю, что клиенту не нужно знать о токене JWT. Пока клиент прикрепляет защищенный файл cookie (содержащий токен), запросы обрабатываются и отклоняются. В случае отклонения клиент должен получить новый токен.

3. Спасибо, мне удалось это реализовать. Вы были полезны.

Ответ №2:

Ваш вариант использования неясен. Я вижу, что вы уже добавили токен в модель, используя model.addAttribute("token", token) , но использовали ли вы его из homepage шаблона? Модель действует как хранилище ключ-значение для обмена информацией с шаблоном представления, и шаблон отвечает за извлечение соответствующей информации и включение ее в ответ, отправляемый обратно клиенту.

Кстати, вы также, похоже, используете password в качестве параметра запроса, который никогда не рекомендуется. Всегда используйте текст HTTP post для такой конфиденциальной информации.

Комментарии:

1. Спасибо за ответ, Нилеш, то, что я пытаюсь сделать, это передать токен в http-ответе и также вернуть страницу. Не возражайте, что я использовал model для установки токена на нем. Я просто хочу отправить токен и страницу отдельно, чтобы я мог отобразить страницу «Вы вошли в систему», а также токен отдельно, чтобы клиент мог использовать его для проверки себя позже. Но если есть альтернативный способ сделать это, пожалуйста, порекомендуйте и это. Я довольно новичок в этом. Спасибо

Ответ №3:

 public String createAuthenticationToken(@RequestParam("userName") String username, @RequestParam("Password") 
String password, Model model, HttpServletResponse response) throws Exception {
    
    authenticate(username, password);
    
    final UserDetails userDetails = userDetailsService.loadUserByUsername(username);
    
    final String token = jwtTokenUtil.generateToken(userDetails);
    
    response.addHeader("token", token);
    model.addAttribute("UserName",username);
    model.addAttribute("token",token);
    return "homepage";
}
  

Это то, что я придумал, добавив заголовок