In my nextJS application the user can do a login (login page), which creates a cookie with a token and redirects to a route (main page), which uses the main component.
In the Main component I'm using getInitialProps to get the cookie token. But this is only working after refreshing the page. So right now I'm logging in and getting redirected. If I click on the button, there is no token. After refreshing the page, I do get a token.
How can I avoid this? I think I'm doing something wrong on server side...
Login
export class Login extends Component {
render () {
return (
<Form id='login' onSubmit={this._onSubmit.bind(this)}>
// Input fields
</Form>
)
}
_onSubmit = (event) => {
event.preventDefault()
const { username, password } = this.state
// Sends mutation request to graphQL server
this.props.signinUserMutation({
variables: { username, password }
}).then(response => {
// Returns token
const token = response.data.token
if (token) {
Cookies.set('auth-token', token)
this.props.client.resetStore().then(() => {
redirect({}, '/main')
})
}
})
}
}
Main
class Main extends Component {
static async getInitialProps (context, apolloClient) {
const { req } = context
const initProps = {}
if (req && req.headers) {
const cookies = req.headers.cookie
if (typeof cookies === 'string') {
const cookiesJSON = jsHttpCookie.parse(cookies)
initProps.token = cookiesJSON['auth-token']
}
}
return initProps
}
clickIt = () => {
console.log(this.props.token)
}
render () {
return (<Button onClick={this.clickIt.bind(this)})
}
}
After login your cookie is saved in browser, so you should use document.cookie
in getInitialProps to get cookie value.
As I understand this code:
if (req && req.headers) {
const cookies = req.headers.cookie
if (typeof cookies === 'string') {
const cookiesJSON = jsHttpCookie.parse(cookies)
initProps.token = cookiesJSON['auth-token']
}
}
is using request header to get cookie value, which will happen only after you make request to the server (when you refresh page). When navigation in browser happens that code doesn't run and you don’t get cookie. Thats why you need to get your cookie directly from browser document.cookie
.
Consider using localStorage for saving auth tokens instead cookie, it has better api.
Since componentDidMount
is executed only in the browser, use it to take cookie value and place it in redux store:
componentDidMount() {
placeTokenInReduxStoreAction(Cookies.get('auth-token'));
}
I assume you use cookies-js
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With