2016-12-25 6 views
2

약간의 연구가 끝나면 JWT는 컴팩트하고 분석하기 쉽기 때문에 로그인 인증에 주로 사용됩니다. 나는 JWT를 사용하여 정착했다. 그러나, 내 질문은 내 redux 패러다임에 이것을 포함하는 방법에 있습니다. 사용자가 자격 증명을 채우고 제출 버튼을 클릭하면 가입 양식이있는 것으로 가정하고 JWT를 만들기위한 작업을 생성하는 작업을 호출합니다. 이제이 동작은 내 응용 프로그램의 백 엔드로 이동하고 응용 프로그램의 백 엔드는 JWT API를 호출합니다. 그래서이 동작은 비동기/rpc 호출입니까? 또한 라우팅은 어떻게 정확하게 발생합니까? 이전에는 반응 라우터를 사용했지만 상용구를 사용했습니다. 이 웹 응용 프로그램을 처음부터 구축하고 있으므로 라우팅을 다루는 위치와 어디에서 처음으로 서버에서 얻은이 토큰을 정확하게 전달할 수 있을지 혼란 스럽습니다. 사용자가 요청할 때마다 토큰이 사용됩니까? 클라이언트는 요청을 할 때마다이 토큰에 대해 어떻게 알 수 있으므로 사용자를 인증 된 상태로 유지할 수 있습니까?react-redux를 사용하여 로그인 인증을 구현하는 방법은 무엇입니까?

답변

3

사용자가 자신의 자격 증명 (이메일/비밀번호)을 제출하면 백엔드가 처음으로 인증하고이 시간에만 백엔드가 이러한 자격 증명을 사용합니다. 인증시 백엔드는 일부 사용자 정보 (보통 사용자 ID 만 포함)를 사용하여 JWT를 작성합니다. 이를 수행하려면 JWT Libraries과 심지어 jwt-decode for javascript이 많이 있습니다. 백엔드는 후속 요청마다 프론트 엔드가 저장하는 JWT (즉, localStorage.setItem('authToken', jwt))로 응답합니다.

사용자는 요청 헤더의 Authorization 키 아래에 JWT와 함께 요청을 보냅니다. 다음과 같음 :

function buildHeaders() { 
    const token = localStorage.getItem('authToken') 

    return { 
     "Accept": "application/json", 
     "Content-Type": "application/json" 
     "Authorization": `${token}` 
    } 
} 

백엔드는 이제 JWT를 디코딩하고 인증합니다. 유효한 JWT 인 경우 요청이 계속되고 그렇지 않은 경우 요청이 거부됩니다.

이제 React-Router를 사용하면 인증 된 경로를 onEnter 기능으로 보호 할 수 있습니다. 제공하는 기능은 필요한 모든 검사를 수행합니다 (JWT의 경우 localStorage를 확인하고 현재 사용자 인 경우).

const _ensureAuthenticated = (nextState, replace) => { 
    const { dispatch } = store 
    const { session } = store.getState() 
    const { currentUser } = session 
    const token = localStorage.getItem("phoenixAuthToken") 
    if (!currentUser && token) {  // if no user but token exist, still verify 
     dispatch(Actions.currentUser()) 
    } else if (!token) {    // if no token at all redirect to sign-in 
     replace({ 
     pathname: "/sign-in", 
     state: { nextPathname: nextState.location.pathname} 
     }) 
    } 
    } 

당신은과 같이 어떤 경로에서이 기능을 사용할 수 있습니다 : 일반적으로 이런 짓을했는지

<Route path="/secret-path" onEnter={_ensureAuthenticated} /> 

체크 아웃 jwt.io JWT의에 대한 자세한 내용 및 반응과 인증에 대한 자세한 내용은 react-router auth-flow example -라우터.

3

나는 개인적으로 비동기 API 호출에 Redux saga을 사용하고, 나는 당신에게 내가 JWT 허가를 사용하고 흐름을 보여줄 것이다 : 당신의 사가에서 사용자 이름과 암호

    1. 파견 LOG_IN 조치를 당신 LOGGING_IN_PROGRESS 예전에 표시 할 작업 보내기 회 전자
    2. API 호출
    3. 검색된 토큰 저장 e.x.

      import request from 'axios'; 
      import {get} from './persist'; // function to get something from localstorage 
      
      export const GET = 'GET'; 
      export const POST = 'POST'; 
      export const PUT = 'PUT'; 
      export const DELETE = 'DELETE'; 
      
      const service = (requestType, url, data = {}, config = {}) => { 
          request.defaults.headers.common.Authorization = get('token') ? `Token ${get('token')}` : ''; 
          switch (requestType) { 
           case GET: { 
            return request.get(url, data, config); 
           } 
           case POST: { 
            return request.post(url, data, config); 
           } 
           case PUT: { 
            return request.put(url, data, config); 
           } 
           case DELETE: { 
            return request.delete(url, data, config); 
           } 
           default: { 
            throw new TypeError('No valid request type provided'); 
           } 
          } 
      }; 
      export default service; 
      

      감사 : 로컬 스토리지에

    4. 파견 LOG_IN_SUCCESS 또는 LOG_IN_FAILED 당신이처럼 보이는,

    지금, 난 항상 내 모든 요청을 처리하기 위해 별도의 기능을 사용하는 거지 어떤 응답 응용 프로그램을 알리는 이 서비스에서 내 앱에서 모든 API 호출에 대한 요청 데이터를 쉽게 설정할 수 있습니다 (로케일도 설정할 수 있음).

    그것의 가장 흥미로운 부분은이 선해야한다 :

    request.defaults.headers.common.Authorization = get('token') ? `Token ${get('token')}` : '';` 
    

    그것은 모든 요청에 ​​JWT 토큰을 설정하거나 필드를 비워 둡니다.

    토큰이 오래되었거나 유효하지 않은 경우 백엔드 API는 모든 API 호출에 대해 401 상태 코드로 응답해야합니다. 그런 다음 무용담 catch 블록에서 원하는 방식으로 오류를 처리 할 수 ​​있습니다.

  • 0

    최근 등록과 로그인을 구현해야만했습니다. & Redux도 마찬가지입니다.

    다음은 로그인 기능과 http auth 헤더 설정을 구현하는 몇 가지 기본 스 니펫입니다.

    이 내 로그인 비동기 행동 작성자 기능입니다 :

    function login(username, password) { 
        return dispatch => { 
         dispatch(request({ username })); 
    
         userService.login(username, password) 
          .then(
           user => { 
            dispatch(success(user)); 
            history.push('/'); 
           }, 
           error => { 
            dispatch(failure(error)); 
            dispatch(alertActions.error(error)); 
           } 
          ); 
        }; 
    
        function request(user) { return { type: userConstants.LOGIN_REQUEST, user } } 
        function success(user) { return { type: userConstants.LOGIN_SUCCESS, user } } 
        function failure(error) { return { type: userConstants.LOGIN_FAILURE, error } } 
    } 
    

    이 API 호출 처리하는 사용자 서비스의 로그인 기능입니다 :

    function login(username, password) { 
        const requestOptions = { 
         method: 'POST', 
         headers: { 'Content-Type': 'application/json' }, 
         body: JSON.stringify({ username, password }) 
        }; 
    
        return fetch('/users/authenticate', requestOptions) 
         .then(response => { 
          if (!response.ok) { 
           return Promise.reject(response.statusText); 
          } 
    
          return response.json(); 
         }) 
         .then(user => { 
          // login successful if there's a jwt token in the response 
          if (user && user.token) { 
           // store user details and jwt token in local storage to keep user logged in between page refreshes 
           localStorage.setItem('user', JSON.stringify(user)); 
          } 
    
          return user; 
         }); 
    } 
    

    가 그리고 이것은이다 도우미 함수는 에 사용 http 요청에 대한 인증 헤더를 설정 :

    export function authHeader() { 
        // return authorization header with jwt token 
        let user = JSON.parse(localStorage.getItem('user')); 
    
        if (user && user.token) { 
         return { 'Authorization': 'Bearer ' + user.token }; 
        } else { 
         return {}; 
        } 
    } 
    
    전체 예를 들어

    및 작업 데모 당신은 this blog post

    에 갈 수
    관련 문제