knock
knock copied to clipboard
Support for Serialization of Knock::AuthToken
How do you feel about supporting serialization of Auth tokens?
I typically create api's that use the jsonapi.org spec (using active_model_serializers) and would like the entire app to use the spec. The default jwt response doesn't fit the spec:
{"jwt":"eyJ0eXAiOiTRSGciOiJIUzI1NiJ9.eyJleIOVU0OTEwNTQ4NTR9.mf4zC-MugaLVQr-Fq9ZdnHG9yYU6QWjIUVUzjjoh3Y"}
The response payload that I think I would like is something like this:
{
"data": {
"id": "eyJ0eXAiOiTRSGciOiJIUzI1NiJ9.eyJleIOVU0OTEwNTQ4NTR9.mf4zC-MugaLVQr-Fq9ZdnHG9yYU6QWjIUVUzjjoh3Y",
"type": "knock_auth_tokens",
"attributes": {
"expiration": 1491168419
}
}
}
The id being the token is strange, I know, but the jsonapi spec requires an ID field.
When I tried to use a custom serializer, I had 2 issues, first:
First Issue
undefined method `read_attribute_for_serialization' for #Knock::AuthToken:0x000000069da6d8
The fix for that is either include ActiveModel::Serialization:
class Knock::AuthToken
include ActiveModel::Serialization
end
OR add a #read_attribute_for_serialization
method, something like this:
class Knock::AuthToken
def read_attribute_for_serialization(key)
self.send(key) if self.respond_to?(key)
end
end
Second Issue (If including ActiveModel::Serialization)
undefined method `id' for #Knock::AuthToken:0x000000057279c8
A fix for that can either be done on the AuthToken object:
class Knock::AuthToken
include ActiveModel::Serialization
def id
self.token
end
end
OR on the serializer:
class Knock::AuthTokenSerializer < ActiveModel::Serializer
def id
object.token
end
end
The solutions above don't really feel right, since they are tied to active model serializations... but support for serialization (or documentation for how to go about serialization) would be great.
I would be happy to contribute if you had some opinions on the solution.
If I am not mistaken, the format that you are trying to achieve is actually for resource objects. JSON API doesn't really say much about how token related responses should be returned.
However, I think you can modify the Knock response by customizing the Knock::AuthTokenController
's create
method.
I believe include ActiveModel::Serialization
is missing in the AuthToken
model?
Still, I managed to get it to work with this:
class AuthTokenSerializer < ActiveModel::Serializer
attributes :jwt, :payload
def jwt
object.token
end
def payload
object.payload
end
end