С чего мне начать, если я хочу, чтобы приложение Spring / React запоминало мою регистрационную информацию при открытии новой вкладки? - PullRequest
0 голосов
/ 13 января 2020

У меня есть веб-приложение, защищенное с помощью JWT. Как сделать так, чтобы он запомнил мои данные для входа и не вводил их снова, если я открою новую вкладку? Я использую ax ios .post для конечной точки аутентификации и сохраняю токен в localStorage. Мой код службы аутентификации во внешнем интерфейсе:

import axios from 'axios'

const API_URL = 'http://localhost:8080/map-runner'

export const USER_NAME_SESSION_ATTRIBUTE_NAME = 'authenticatedUser'

class AuthenticationService {

    executeJwtAuthenticationService(username, password) {
        return axios.post(`${API_URL}/authenticate`, {
            username,
            password
        })
    }

    registerSuccessfulLoginForJwt(username, token) {
        sessionStorage.setItem(USER_NAME_SESSION_ATTRIBUTE_NAME, username)
        localStorage.setItem("token", token)
    }

    createJWTToken(token) {
        return 'Bearer ' + token
    }


    logout() {
        sessionStorage.removeItem(USER_NAME_SESSION_ATTRIBUTE_NAME);
    }

    isUserLoggedIn() {
        let user = sessionStorage.getItem(USER_NAME_SESSION_ATTRIBUTE_NAME)
        if (user === null) return false
        return true
    }

    getLoggedInUserName() {
        let user = sessionStorage.getItem(USER_NAME_SESSION_ATTRIBUTE_NAME)
        if (user === null) return ''
        return user
    }

    setupAxiosInterceptors(token) {
        axios.interceptors.request.use(
            (config) => {
                if (this.isUserLoggedIn()) {
                    config.headers.authorization = token
                }
                return config
            }
        )
    }
}

export default new AuthenticationService()

Теперь мой компонент входа:

import React, { Component } from 'react'
import AuthenticationService from '../service/AuthenticationService';

class LoginComponent extends Component {

    constructor(props) {
        super(props)

        this.state = {
            username: '',
            password: '',
            hasLoginFailed: false,
            showSuccessMessage: false
        }
    }

    handleChange = (event) => {
        this.setState(
            {
                [event.target.name]
                    : event.target.value
            }
        )
    }

    loginClicked = () => {
        AuthenticationService
            .executeJwtAuthenticationService(this.state.username, this.state.password)
            .then((response) => {
                AuthenticationService.registerSuccessfulLoginForJwt(this.state.username, response.data.token)
                console.log(response.data.token);
                this.props.history.push(`/calculations`)
            }).catch(() => {
                this.setState({ showSuccessMessage: false })
                this.setState({ hasLoginFailed: true })
            })
    }

    render() {
        return (
            <div>
                <h1>Вход</h1>
                <div className="container">
                    {this.state.hasLoginFailed && <div className="alert alert-warning">Неверные данные</div>}
                    {this.state.showSuccessMessage && <div>Вход выполнен успешно</div>}
                    Имя пользователя: <input type="text" name="username" value={this.state.username} onChange={this.handleChange} />
                    Пароль: <input type="password" name="password" value={this.state.password} onChange={this.handleChange} />
                    <button className="btn btn-success" onClick={this.loginClicked}>Вход</button>
                </div>
            </div>
        )
    }
}

export default LoginComponent

Бэкенд в весенней загрузке довольно длинный, даже в части JWT, поэтому я думаю, что оставлю ссылку на туториал, который был основой моего бэкенда. Пути немного отличаются, но в целом эти части бэкэнда одинаковы. Я также пытался использовать sessionstorage вместо localalstorage, не работает. Если возможно, возможно, мы сможем протестировать все сначала, реплицируя весь учебный код, так как часть jwt там почти одинакова (у меня есть копия, и у них есть ссылка на их github в статье)

Ответы [ 2 ]

1 голос
/ 13 января 2020

У вас должна быть страница входа в систему, где вы будете отправлять токен jwt во время входа в систему, поэтому сохраняйте токен jwt во время входа в систему как

 axios.post("http:yourAPIaddresshere", formData)
    .then((response) => {
       if(response.status === 200) {
          // storing session 
          localStorage.setItem('session', response.data.token)
          this.props.history.push('home');
        } else {
          this.showMessage('Error message', "Please check your credentials.")
        }
      } 
    });
}

. Здесь ваш сеанс хранится в localStorage. теперь в других все файлы извлекают токен. В том же файле входа в систему также выполните:

 componentDidMount(){
       if (localStorage.getItem('session') !== null) {
         this.props.history.push('home')
       }
     }

это всегда будет sh вашей навигацией к другим вкладкам. Чтобы сделать другие ваши вкладки / страницы безопасными, также проверьте сеанс, если он не равен нулю, он не позволит вам открывать другие страницы с использованием маршрутов без маркера сеанса

 componentDidMount(){
       if (localStorage.getItem('session') === null)
     this.props.history.push('login') }

PS: Убедитесь, что во время Выйти как:

 localStorage.removeItem('session');
1 голос
/ 13 января 2020

Вы можете сохранить токен либо в локальном хранилище, либо приготовить ie. И каждый раз, когда вы отправляете любой запрос xhr, вы можете передавать токен в заголовке.

...