我一直在尝试使用react和next实现redux-observable服务器端呈现,现在我想实现auth
登录
访问需要验证的网页
token
的Cookie
以上步骤发生在史诗内部,如下所示
/epics/signin.js
export const signinEpic = (action$, store) => action$
.ofType(SIGNIN)
.mergeMap(() => {
const params = { ... }
return ajax(params)
.concatMap((response) => {
const { name, refreshToken } = response.body
if (refreshToken && name === 'TokenExpiredError') {
const refreshParams = { ... }
return ajax(refreshParams)
.concatMap((refreshResponse) => {
setToken(refreshResponse.body.auth.token)
const me = { ... }
return [
authSetMe(me),
signinSuccess(),
]
})
.catch(error => of(signinFailure(error)))
}
const me = { ... }
setToken(response.body.auth.token)
return [
authSetMe(me),
signinSuccess(),
]
})
.catch(error => of(signinFailure(error)))
})
我做了一些console.log(Cookies.get('token'))
以确保cookie被保存,并且它打印令牌就好了,说它在那里,但当我在浏览器控制台下检查>申请>饼干,什么都没有
因此,在下面的auth epic中,getToken()
将始终返回''
,它始终会发送authMeFailure(error)
/epics/auth.js
// this epic will run on pages that requires auth by dispatching `authMe()`
export const authMeEpic = action$ => action$
.ofType(AUTH_ME)
.mergeMap(() => {
const params = {
...,
data: {
...
Authorization: getToken() ? getToken() : '', // this will always return ''
},
}
return ajax(params)
.mergeMap((response) => {
const { name, refreshToken } = response.body
if (refreshToken && name === 'TokenExpiredError') {
const refreshParams = { ... }
return ajax(refreshParams)
.mergeMap((refreshResponse) => {
setToken(refreshResponse.body.auth.token)
const me = { ... }
return authMeSuccess(me)
})
.catch(error => of(authMeFailure(error)))
}
const me = { ... }
setToken(response.body.auth.token)
return authMeSuccess(me)
})
.catch(error => of(authMeFailure(error)))
})
我使用js-cookie来获取和设置Cookie
编辑:我实际上准备了一个包含getToken,setToken和removeToken的auth lib,如下所示
import Cookies from 'js-cookie'
export const isAuthenticated = () => {
const token = Cookies.get('token')
return !!token
}
export const getToken = () => Cookies.get('token')
export const setToken = token => Cookies.set('token', token)
export const removeToken = () => Cookies.remove('token')
是的,我本来可以在史诗上使用setToken()
,只是试图直接测试cookie集方法
更新:
console.log(getToken())
打印正确的标记更新#2:
好吧我认为我设法让它工作,事实证明我们需要两种类型的cookie,服务器端(刷新时生成的一个)和客户端(持续导航),所以我不是'能够在史诗上获得令牌,因为它没有从服务器端传递(至少这是我的理解)
答案 0 :(得分:0)
受github上的这个问题comment的启发
yarn add cookie-parser
./server.js
上的(您需要有一个自定义服务器才能执行此操作)
const cookieParser = require('cookie-parser')
...
server.use(cookieParser())
on ./pages/_document.js
export default class extends Document {
static async getInitialProps(...args) {
// ...args in your case would probably be req
const token = args[0].req ? getServerToken(args[0].req) : getToken()
return {
...
token,
}
}
render() {
...
}
}
在./lib/auth.js
或您放置令牌方法的任何地方
export const getServerToken = (req) => {
const { token = '' } = req.cookies
return token
}
export const getToken = () => {
return Cookies.get('token') ? Cookies.get('token') : ''
}
我不是百分之百了解这是如何解决我的问题,但我现在就这样离开