【问题标题】:React render run before fetch method receives token from server在 fetch 方法从服务器接收令牌之前运行 React 渲染
【发布时间】:2018-11-25 18:45:16
【问题描述】:

我的 React 应用程序中有一个 JS 文件,它连接到服务器,发送用户名和密码,从服务器接收一个 oauth 令牌并将令牌存储在本地存储中。 然而,在 react 收到令牌之前,react 会在令牌存储在本地存储之前发送下一个请求。这会导致 401 未经授权的访问。

AuthService.js

 login(username, password) {
    console.log(username);
     return this.fetch(`${this.domain}/api/AuthAPI/getCredentials`, {
        headers: {
            'Access-Control-Allow-Origin': "*"    
        }
    }).then(res => {
        this.fetch(`${this.domain}/Token`, {
            method: 'POST',
            body: 'grant_type=password&username=' + res[0]
        }).then(response => {
            var date_token_issue = new Date();
            this.setToken(response.access_token,response.expires_in, date_token_issue) // Setting the token in localStorage
            return Promise.resolve(response);
        })
    })

}

setToken(idToken,expires, date_token_issue ) {
    localStorage.setItem('id_token', idToken)
    localStorage.setItem('expires', expires)
    localStorage.setItem('date_token_issue', date_token_issue)
}

SignIn.jsx

import React, { Component } from 'react'
import AuthService from '../comonents/AuthService';
import Orders from '../../app/orders/orders'
import { Redirect, Switch, Route} from "react-router-dom";
export default function SignIn(AuthComponent){
const Auth = new AuthService('http://localhost:53050');

return class AuthWrapped extends Component {
  constructor() {
    super();
    this.state = {
        user: null,
        loggedIn: false
    }
}

async componentDidMount() {
  if (!Auth.loggedIn()) {
    const promise = await  Auth.login('m.dawaina', 'm.dawaina');
    console.log(promise)
    this.setState({loggedIn: true});
  }
  else {
      try {            
        this.setState({loggedIn: true})
          const profile = Auth.getProfile()
          this.setState({
              user: profile
          })               
      }
      catch(err){
          Auth.logout()
          //this.props.history.replace('/login')
      }
  }
 }

render() {
if (this.state.loggedIn) {      

    return (
      <div>  
        <Redirect to='/orders'/>       
        <Switch>
          <Route path="/orders" component={Orders} />         
        </Switch>
      </div>
    )
}
else {
  return (       
          <AuthComponent history={this.props.history} user={this.state.user} />
         )
     }
   }

 }
}

我需要一种方法来强制 react 等待 JS 接收到令牌并将其存储在本地存储中,并阻止 react 发送下一个请求,直到它找到存储在本地存储中的令牌。

【问题讨论】:

    标签: reactjs asynchronous oauth token fetch


    【解决方案1】:
    login(username, password) {
    console.log(username);
     return this.fetch(`${this.domain}/api/AuthAPI/getCredentials`, {
        headers: {
            'Access-Control-Allow-Origin': "*"    
        }
    }).then(res => {
        // Add a return here
        return this.fetch(`${this.domain}/Token`, {
            method: 'POST',
            body: 'grant_type=password&username=' + res[0]
        }).then(response => {
            var date_token_issue = new Date();
            this.setToken(response.access_token,response.expires_in, date_token_issue) // Setting the token in localStorage
            return Promise.resolve(response);
        })
    })
    

    您需要在 then 函数中添加一个 return,以便 await 等待内部 promise 解决。

    【讨论】:

    • 感谢 Sibin 的宝贵回答。 console.log(promise) 现在返回令牌。但是,请求仍然没有令牌发送。虽然当我刷新页面时使用令牌发送的请求
    • ConfigureStore 在令牌存储在本地存储之前运行,我该如何防止这种情况
    • 你在使用 redux 吗?您如何调用 ConfigureStore?
    • const client = axios.create({ responseType: 'json' }); client.defaults.headers.common['Authorization'] = 'Bearer' + Auth.getToken(); console.log('ttt'+ Auth.getToken()); export const configureStore = preloadedState => { const store = createStore( reducers, //自定义reducers preloadedState, composeWithDevTools(applyMiddleware(thunk, axiosMiddleware(axios.create(axiosMiddleware(client)))), //第二个参数options可以可选包含onSuccess, onError, onComplete, successSuffix, errorSuffix )) ) 返回存储; };
    • 我像这样从 index.js 调用配置存储
    猜你喜欢
    • 1970-01-01
    • 2020-09-13
    • 2015-05-07
    • 2021-10-16
    • 2020-11-11
    • 2021-10-02
    • 2020-04-02
    • 2018-04-21
    • 2020-11-14
    相关资源
    最近更新 更多