I am using prisma to work with the GraphQL. I know there is a way to secure the graphql server with a secret key. For example on specifying the secret key as:
secret: my-secret-42
in prisma.yml
, and then running prisma deploy
will secure the graphql server and all the subsequent queries will need a JWT token to access it.
I am able to generate the JWT token using the command
prisma token
This gives me the token and on passing it in the headers, I am able to access it. But is there an API using which I could generate the token and I do not have to manually run the prisma token
command on the CLI.
I want the javascript to directly access the GraphQL via queries. For this, I need some form of authentication to happen. Since there would be multiple users using the application, I want to have different tokens for different users. Thus I am looking for a way where I could generate the token using the API if available with Prisma.
The service token is a simple JWT token that can easily be created by using service and stage name, as well as the secret. You can create the token yourself and attach it. Take a look at the actual code the prisma CLI is using:
getToken(serviceName: string, stageName: string): string | undefined {
if (this.secrets) {
const data = {
data: {
service: `${serviceName}@${stageName}`,
roles: ['admin'],
},
}
return jwt.sign(data, this.secrets[0], {
expiresIn: '7d',
})
}
return undefined
}
Source: https://github.com/prisma/prisma/blob/master/cli/packages/prisma-yml/src/PrismaDefinition.ts
More information regarding the structure:
Service tokens follow the JSON Web Token (JWT) specification (RFC 7519):
"JSON Web Token (JWT) is a compact, URL-safe means of representing claims to be transferred between two parties. The claims in a JWT are encoded as a JSON object that is used as the payload of a JSON Web Signature (JWS) structure or as the plaintext of a JSON Web Encryption (JWE) structure, enabling the claims to be digitally signed or integrity protected with a Message Authentication Code (MAC) and/or encrypted."
A JWT has the following three components:
Header: The header typically consists of two parts: the type of the token, which is JWT, and the hashing algorithm being used (which is HS256 in the case of Prisma service tokens).
{ "alg": "HS256", "typ": "JWT" }
Payload: The payload contains the claims. Claims are statements about an entity (typically, the user) and additional data. Here is what it looks like for a service called demo deployed to the dev stage:
{
"data": {
"service": "demo@dev",
"roles": ["admin"]
},
"iat": 1532530208,
"exp": 1533135008
}
Signature: The signature is used to verify the message wasn't changed along the way. To create the signature part you have to take the encoded header, the encoded payload, a secret, the algorithm specified in the header, and sign that. For example if you want to use the HMAC SHA256 algorithm, the signature will be created in the following way:
HMACSHA256(base64UrlEncode(header) + '.' + base64UrlEncode(payload), secret)
Therefore, a JWT typically looks like this: xxxxx.yyyyy.zzzzz
Source: https://www.prisma.io/docs/prisma-server/authentication-and-security-kke4/#service-token