我一直在更改这个项目:https://github.com/viewflow/cookbook/tree/master/_articles/redux_jwt_auth
为了更好地理解react / redux以及如何将其实现到像Django这样的后端框架中,但是我很困惑。我正在尝试实现注销功能,但是我不了解基于作者action / auth.js中其他变量的注销外观。
我知道我必须销毁JWTToken,但我不太了解他如何在项目中实现令牌。我已经多次阅读过他的article,但我仍然不太了解。
答案 0 :(得分:0)
有些人在国外研究范围内的问题,但是np我得到了你,我希望我能对这里发生的事情给出一个很好的概述。
TL; DR,middleware.js是发生魔术的地方,并且JWT令牌无法销毁,它们只会过期,您可以在不想使用它们的情况下将它们从客户端应用程序中删除。
免责声明: :我没有使用下面列出的三个软件包中的任何一个 以前,如果我错了,请纠正我。
我强烈建议您阅读code base中使用的软件包,尤其是:
我想我将把这个东西分成两部分:
1)如何获取令牌:
可以通过使用POST
向/api/auth/token/obtain/
发送username and password
请求来获取令牌,这是在redux-api-middleware
中配置的frontend/src/middleware.js
的帮助下完成的。并应用于redux存储,这使我们能够使用API
导入在action/auth.js
中发出RSAA
个请求。
注意::在package.json中将 proxy 设置为https://localhost:8000 这就是为什么我们仅在发出RSAA请求时指定endopint,CRA足够聪明,可以使用该代理
2)如何刷新令牌:
frontend/src/middleware.js
文件负责完成两项任务:
加上它作为中间件的主要工作(拦截通过中间件链进行的动作)。
在分派动作时,中间件将检查该动作是否不是RSAA
动作,请正常分派,否则,如果是RSAA
动作,则检查令牌:
这里有两种情况:(A,B)
A。如果商店中有访问令牌和刷新令牌,但是访问令牌已过期:
中间件将推迟操作(将其推送到等待列表),如果等待列表中至少有一个等待The current action being dispatched
的操作,则意味着此操作在这里,因为我们需要刷新访问令牌,那么此行将运行rsaaMiddleware(nextCheckPostoned)(refreshAccessToken(refreshToken))
,这基本上意味着
currying rsaaMiddleware(func1)(func2)
换句话说,然后调用func2并可以访问func1中的返回值 ,为什么这样做?可以访问分派refreshAccessToken(refreshToken)时返回的操作类型,它是TOKEN_RECEIVED
还是TOKEN_FAILURE
?如果我们获得了令牌,我们将进行调度并将新令牌存储到状态pass it down to be dispatch normally
的操作,然后遍历waiting-list
中的所有操作并在它们上使用rsaaMiddleware(apiMiddleware)记住我们的不幸动作?之后,我们清除了wait-list
,但是如果没有得到令牌the reducer returned TOKEN_FAILURE
,我们就将其传递给正常分发(将操作传递给redux中间件链中的下一个中间件)>
注意::rsaaMiddleware是apiMiddleware,它是使 HTTP请求。
B。否则:
意味着访问令牌仍然有效,在这种情况下,我们只需使用rsaaMiddleware
并使其生效即可。
我知道我的英语不好,这是带字幕的相同代码
frontend/src/middleware.js
import { isRSAA, apiMiddleware } from 'redux-api-middleware';
import { TOKEN_RECEIVED, refreshAccessToken } from './actions/auth'
import { refreshToken, isAccessTokenExpired } from './reducers'
export function createApiMiddleware() {
let postponedRSAAs = [] // The list of waiting actions
// This middleware actual form, having access to getState and dispatch thanks for redux/applyMiddleware
return ({ dispatch, getState }) => {
const rsaaMiddleware = apiMiddleware({dispatch, getState}) // Aliasing the apiMiddleware to rsaaMiddleware
// The point in the middleware where we handle the action (this is the whole point of middlewares)
return (next) => (action) => { // action: the action dispatched, next: forget me execute the next middleware
const nextCheckPostoned = (nextAction) => { // nextAction: The action we get when we curry this function
if (nextAction.type === TOKEN_RECEIVED) { // If we got the new access token
next(nextAction); // pass this action down the middleware chain normally to modify the state
postponedRSAAs.forEach((postponed) => { // Run all waiting actions after token refresh
rsaaMiddleware(next)(postponed) // calling the api with the waiting action
})
postponedRSAAs = [] // clearing the wait-list, since the have been all called above
} else { // if we didn't get the token
next(nextAction) // pass this action down the middleware chain normally to modify the state
}
}
if(isRSAA(action)) { // If the action being dispatched is an RSAA action
const state = getState(),
token = refreshToken(state) // The refresh token
if(token && isAccessTokenExpired(state)) { // A. If there is a an access and refresh tokens in the store but the access token is expired :
postponedRSAAs.push(action) // Add the action to the wait list
if(postponedRSAAs.length === 1) { // If there is at least one waiting action
return rsaaMiddleware(nextCheckPostoned)(refreshAccessToken(token)) // request a new access token and handle the result to the nextCheckPostoned function
} else {
return // Return from this scope (which is done by just)
}
}
// B. Otherwise: Means that the access token is still valid, in that case we just use the rsaaMiddleware and let it do it's thing.
return rsaaMiddleware(next)(action); // NOTE: The rsaaMiddleware is the actuall apiMiddleware
}
return next(action); // pass the action down the middleware chain
}
}
}
export default createApiMiddleware();
代码库可以使用一些重构,例如,在第29行的middleware.js
文件token = refreshToken(state)
中,应重命名为refreshToken = refreshToken(state)
,以使代码更具可读性。
好的,就是关于JWT集成在此代码库中的工作方式,
我会让您弄清楚如何实现注销“功能”
提示:了解工作原理的一个好方法是保留在这种情况下运行的第一个文件
frontend/src/index.js
,然后一直按照说明进行操作。兔子洞。