I try to get value of an username
field inside of a JWT
from DRF
response
using VueJs
, I set my initial state inside a vuex
module:
function initialState() {
return {
accessKey: null,
refreshKey: null,
username: '',
alertMessage: null,
}
}
export const mutations = {
setUserKey(state, payload) {
state.accessKey = payload.accessKey;
state.refreshKey = payload.refreshKey;
state.username = payload.username;
state.expiration = Date.now() + 1
},
};
export const actions = {
async loginUser(context, payload) {
try {
const response = await DjangoAPI.login(payload);
context.commit('setUserKey',{
accessKey: response.data.access,
refreshKey: response.data.refresh,
username: response.data.username
});
return Promise.resolve(response);
} catch(err) {
console.log('err in user.actions/loginUser', err)
return Promise.reject(err);
}
},
};
export default {
namespaced: true,
state: initialState,
getters,
actions,
mutations
}
when I check vuex
initial values in localStorage
i can see username
field:
user: {accessKey: null, refreshKey: null, expiration: 0, username: ""}
accessKey: null
alertMessage: null
expiration: 0
refreshKey: null
username: ""
But after login, I can get other values but username field is lost:
user: {,…}
accessKey: "eyJ0eXAi...PmQU_I"
alertMessage: null
expiration: 1590318917105
refreshKey: "eyJ0eXA...GdCgI"
if I check JWT
values, I can see username
in my payload
:
{
"token_type": "access",
"exp": 1590319633,
"jti": "1556edbab9dd47349138fd98a1f8babc",
"user_id": 1,
"username": "ytsejam",
"bio": "",
"iat": 1590316033
}
Why does username
field is removed after response
?
Thanks
edit1:
console.log(response):
{data: {…}, status: 200, statusText: "OK", headers: {…}, config: {…}, …}
config: {url: "/api/obtain/token/", method: "post", data: "{"username":"ytsejam","password":"ne12veryt.."}", headers: {…}, baseURL: "http://localhost:8000/", …}
data:
access: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNTkwMzIyMzc5LCJqdGkiOiIyNDJjNTA3YzM0MWU0N2Y3OTE0MGU0YmNjNGQ5NWQ1MSIsInVzZXJfaWQiOjEsInVzZXJuYW1lIjoieXRzZWphbSIsImJpbyI6IiJ9.--7cLjVFAvYG8G0TCGh5_6J2foE2h0lEa9K8okUYN4U"
refresh: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImV4cCI6MTU5MTUzMTY3OSwianRpIjoiMjQ0Y2UxMTgzNDk5NDFiZDk4YjlmYTk1MGRkMjdkZTEiLCJ1c2VyX2lkIjoxLCJ1c2VybmFtZSI6Inl0c2VqYW0iLCJiaW8iOiIifQ.b_ONU8yR4LculKQOyw_6aNZnvGdOWbruV48_OhNKYhU"
__proto__: Object
headers: {access-control-allow-credentials: "true", access-control-allow-origin: "http://localhost:8000", allow: "POST, OPTIONS", content-language: "tr", content-length: "518", …}
request: XMLHttpRequest {readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, onreadystatechange: ƒ, …}
status: 200
statusText: "OK"
__proto__: Object
DRF
view using SimpleJWT
package:
class MyTokenObtainPairSerializer(TokenObtainPairSerializer):
@classmethod
def get_token(cls, user):
token = super(MyTokenObtainPairSerializer, cls).get_token(user)
# Add custom claims
token['username'] = user.username
token['bio'] = user.bio
return token
class ObtainTokenPairWithColorView(TokenObtainPairView):
serializer_class = MyTokenObtainPairSerializer
The recommended approach to add custom fields to JWT response is to rewrite the validate() method instead of get_token():
class MyTokenObtainPairSerializer(TokenObtainPairSerializer):
def validate(self, attrs):
data = super().validate(attrs)
refresh = self.get_token(self.user)
data['refresh'] = str(refresh)
data['access'] = str(refresh.access_token)
# Add custom claims
data['username'] = self.user.username
data['bio'] = self.user.bio
return data
Then you will have 'username' and 'bio' fields in response.data, along with 'access' and 'refresh'.