And*_*zo1 9 javascript typescript reactjs
我正在寻找一种干净的方法来在 React 中存储我的访问令牌。
经过一番研究,我发现使用全局变量是获得我想要的东西的有效“欺骗”。但是,我猜测是否有更清晰的方法来获得相同的结果。
//token.js
const access_token= "";
export const setAccessToken(token){
access_token=token;
}
export const getAccessToken(){
return access_token;
}
//NOTICE:
// -ON LOGIN/REFRESH: I set the access token
// -ON API CALLS: I get the access token and I add it to the header
Run Code Online (Sandbox Code Playgroud)
api.js
const baseURL= "http://my_base_url";
const generateApiInterface = ()=>{
let headers : any= {
};
token=getAccessToken(); //HERE I NEED TO RETRIEVE MY ACCESS TOKEN
if(token){
headers={
'Authorization': 'Token '+ token,
...headers //append other basic proprieties
}
}
return axios.create({
baseURL: baseURL,
headers: headers
});
}
const api = generateApiInterface();
Run Code Online (Sandbox Code Playgroud)
您这样做的方式最好将所有内容都保留在内存中。如果这是服务器端,那么您需要确保完成后删除令牌,但如果不是,那么当前的方法是可取的。请注意,您正在使用 a const
,您希望将其更改为 a let
。另一个想法是使用会话存储,但这带来了 XSS 的想法。
然而,React 提供了一种拥有“全局”状态的方法 - 这将是使用提供者和上下文。这是一个例子:
// provider.tsx
import React, { useContext, createContext, FC, useState } from 'react'
type AccessTokenContext = [string, React.Dispatch<React.SetStateAction<string>>]
const AccessTokenProvider: FC = (props) => {
const [accessToken, setAccessToken] = useState<string>(null)
return <AccessToken.Provider value={[accessToken, setAccessToken]} {...props} />
}
const AccessToken = createContext<AccessTokenContext>(null)
const useAccessToken = (): AccessTokenContext => useContext<AccessTokenContext>(AccessToken)
export { AccessTokenProvider, useAccessToken }
Run Code Online (Sandbox Code Playgroud)
您必须将应用程序容器包装在AccessTokenProvider
:
// index.tsx
import React from 'react'
import ReactDOM from 'react-dom'
import './index.css'
import App from './App'
import { AccessTokenProvider } from './providers/AccessTokenProvider'
ReactDOM.render(
<AccessTokenProvider>
<App />
</AccessTokenProvider>,
document.getElementById('app')
)
Run Code Online (Sandbox Code Playgroud)
useAccessToken
然后您就可以使用中的钩子App
以及 的任何子级App
。当然,该提供程序不必是根级别,但将其包含在此处是最简单的。
// app.tsx
import React, { FC } from 'react'
const App: FC = props => {
const [accessToken, setAccessToken] = useAccessToken()
return <div>{/* content */}</div>
}
export default App
Run Code Online (Sandbox Code Playgroud)