Tools: Django + Next.js + Django-GraphQL-JWT
What works: I can login the user and obtain a JWT token, which I save in addition to saving the token in the localStorage to retrieve and verify later.
What does not work: I can successfully retrieve the localStorage token, but when I try to use the library to verify the token on the server, I get this error:
[GraphQL error]: Message: Error decoding signature, Location: [object Object], Path: verifyToken
Verification code:
const [authToken, setAuthToken] = useState(null);
const [localToken, setLocalToken] = useState();
useEffect(() => {
setLocalToken(localStorage.getItem("token"));
}, []);
...
const verifyToken = async () => {
const client = createApolloClient();
const data = await client.mutate({
mutation: verifyMutation,
variables: { token: localToken },
});
if (data) {
setAuthToken(data.data.tokenAuth.token);
}
return data;
};
...
Mutation:
export const verifyMutation = gql`
mutation VerifyToken($token: String!) {
verifyToken(token: $token) {
payload
}
}
`;
schema.py:
class Mutation(graphene.ObjectType):
token_auth = graphql_jwt.ObtainJSONWebToken.Field()
verify_token = graphql_jwt.Verify.Field()
refresh_token = graphql_jwt.Refresh.Field()
revoke_token = graphql_jwt.Revoke.Field()
Here is what happens when I try this manually in GraphQL:
If my mutation includes the token:
mutation VerifyToken($token: String!) {
verifyToken(token: "token_string_here") {
payload
}
}
returns:
{
"errors": [
{
"message": "Variable '$token' is never used in operation 'VerifyToken'.",
"locations": [
{
"line": 1,
"column": 22
}
],
"path": null
}
]
}
However, if I do not include the token as such:
mutation VerifyToken {
verifyToken {
payload
}
}
returns:
{
"data": {
"verifyToken": {
"payload": {
"username": "myname",
"exp": 1623076467,
"origIat": 1623076167
}
}
}
}
Other things I have tried: I have found some reference to SECRET_KEY being an issue with decoding but I have set it in my settings without any improvement in the problem. I have not found any other solutions that would seem to work here.
I have also tried using a custom JWT_VERIFY module but this did not help me fix the problem.
Wow, ok then. So the login portion wasn't working for me initially until I used this code taken from another tutorial:
localStorage.setItem("token", JSON.stringify(data.data.tokenAuth.token));
I didn't realize that the token was being set with a different format and thus does not match what the token looks like in the JWT.
Changing the code to the following this solved the issue! Hope this helps someone else:
localStorage.setItem("token", data.data.tokenAuth.token);