`JWSError JWSInvalidSignature`-Error on firebase
See original GitHub issueI have a project using docker-compose:
version: '3.7'
services:
db:
image: 'mdillon/postgis'
# specify container name to make it easier to run commands.
# for example, you could run docker exec -i postgres psql -U postgres postgres < schema.sql to run an SQL file against the Postgres database
container_name: v_db
restart: always
env_file:
- ./.env
ports:
# make the Postgres database accessible from outside the Docker container on port 5432
- '5432:5432'
volumes:
- db_data:/var/lib/postgresql/data
- sik_data:/shared
# hasura needs higher max_locks_per_transaction
command: postgres -c max_locks_per_transaction=2000
auth:
build:
context: ./auth
container_name: v_auth
restart: always
env_file:
- ./.env
expose:
- '7000'
ports:
- '7000:7000'
depends_on:
- db
- graphql
graphql:
image: 'hasura/graphql-engine:v1.1.0'
container_name: v_graphql
ports:
- '8080:8080'
depends_on:
- db
restart: always
env_file:
- ./.env
command:
- graphql-engine
- serve
caddy:
image: 'caddy/caddy:alpine'
container_name: v_caddy
depends_on:
- db
- graphql
restart: always
ports:
- '80:80'
- '443:443'
volumes:
- ./caddy/Caddyfile:/etc/caddy/Caddyfile
- caddy_certs:/data/caddy
- caddy_config:/root/.config/caddy
volumes:
db_data:
caddy_certs:
sik_data:
caddy_config:
This is the server.js file in the auth server:
'use strict'
// see: https://nodejs.org/de/docs/guides/nodejs-docker-webapp/
const Hapi = require('@hapi/hapi')
// see: https://firebase.google.com/docs/auth/admin/manage-users
const admin = require('firebase-admin')
const postgres = require('postgres')
const serviceAccount = require('./config.js')
const server = new Hapi.Server({
host: '0.0.0.0',
port: 7000,
})
const sql = postgres(process.env.HASURA_GRAPHQL_DATABASE_URL)
let firebaseInitializationError = null
// Initialize the Firebase admin SDK with your service account credentials
if (serviceAccount) {
try {
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
})
} catch (e) {
firebaseInitializationError = e
}
}
async function start() {
server.route({
method: 'GET',
path: '/{uid}',
handler: async (req, h) => {
//console.log('serviceAccount:', serviceAccount)
// Throw 500 if firebase is not configured
if (!serviceAccount) {
return h.response('Firebase not configured').code(500)
}
// Check for errors initializing firebase SDK
if (firebaseInitializationError) {
console.log('firebaseInitializationError:', firebaseInitializationError)
return h
.response(
`firebase initalization error: ${firebaseInitializationError.message}`,
)
.code(500)
}
const { uid } = req.params
//console.log('uid:', uid)
if (!uid) {
return h.response('no uid was passed').code(500)
}
//console.log('will query now')
// fetch id and user_role
return sql`select * from person where account_id = ${uid}`
.then(persons => {
//console.log('persons from query result:', persons)
if (!persons) {
return h.response('Got no persons when querying db').code(500)
}
const person = persons[0]
if (!person) {
return h.response('Got no person when querying db').code(500)
}
const { id, user_role } = person
if (!id) {
return h.response('Got no person_id when querying db').code(500)
}
if (!user_role) {
return h
.response('Got no person-user_role when querying db')
.code(500)
}
const hasuraVariables = {
'https://hasura.io/jwt/claims': {
'x-hasura-default-role': user_role,
'x-hasura-allowed-roles': [user_role],
'x-hasura-user-id': id,
},
}
return admin
.auth()
.createCustomToken(uid, hasuraVariables)
.then(customToken => {
//console.log('customToken:', customToken)
// Send token back to client
return h.response(customToken)
})
.catch(adminError => {
console.log('Error creating custom token:', adminError)
h.response(
`Error creating custom token: ${adminError.message}`,
).code(500)
})
})
.catch(sqlError => {
console.log('Error querying db:', sqlError)
h.response(`Error querying db: ${sqlError.message}`).code(500)
})
},
})
await server.start()
console.log('JSON-API-Server running at:', server.info.uri)
}
process.on('unhandledRejection', err => {
console.log(err)
process.exit(1)
})
start()
The auth server returns a token generated by above code. The token is declared valid on jwt.io but only if declared as HS256, not when declared as RS256. Which baffles me.
This returned token is used client side to sing in:
let res
try {
res = await axios.get(`https://auth.vermehrung.ch/${user.uid}`)
} catch (error) {
return console.log(error)
}
const token = res.data
firebase
.auth()
.signInWithCustomToken(token)
.catch(error => {
console.log('Error signing in with custom token:', error)
})
This works fine.
What does not work is the calls to hasura.
If I set the type in the .env file of docker to HS256:
HASURA_GRAPHQL_JWT_SECRET={"type":"HS256", "jwk_url": "https://www.googleapis.com/service_accounts/v1/jwk/securetoken@system.gserviceaccount.com", "audience": "vermehrung-f48c4", "issuer": "https://securetoken.google.com/vermehrung-f48c4"}
The error is:
{
"type": "http-log",
"timestamp": "2020-03-10T13:06:52.020+0000",
"level": "error",
"detail": {
"operation": {
"error": {
"path": "$",
"error": "Malformed Authorization header",
"code": "invalid-headers"
},
"request_id": "90e5647f-579c-4bac-9d88-3bf83c89ba80",
"response_size": 78,
"raw_query": "{\"operationName\":\"TreeQueryForRoot\",\"variables\":{\"artFilter\":{\"id\":{\"_is_null\":false}},\"eventFilter\":{\"id\":{\"_is_null\":false}},\"gartenFilter\":{\"id\":{\"_is_null\":false},\"aktiv\":{\"_eq\":true}},\"kulturFilter\":{\"id\":{\"_is_null\":false},\"aktiv\":{\"_eq\":true}},\"herkunftFilter\":{\"id\":{\"_is_null\":false}},\"personFilter\":{\"id\":{\"_is_null\":false},\"aktiv\":{\"_eq\":true}},\"sammlungFilter\":{\"id\":{\"_is_null\":false}},\"lieferungFilter\":{\"id\":{\"_is_null\":false}},\"sammelLieferungFilter\":{\"id\":{\"_is_null\":false}},\"teilkulturFilter\":{\"id\":{\"_is_null\":false}},\"zaehlungFilter\":{\"id\":{\"_is_null\":false}}},\"query\":\"query TreeQueryForRoot($artFilter: art_bool_exp!, $eventFilter: event_bool_exp!, $gartenFilter: garten_bool_exp!, $kulturFilter: kultur_bool_exp!, $herkunftFilter: herkunft_bool_exp!, $personFilter: person_bool_exp!, $sammlungFilter: sammlung_bool_exp!, $teilkulturFilter: teilkultur_bool_exp!, $zaehlungFilter: zaehlung_bool_exp!, $lieferungFilter: lieferung_bool_exp!, $sammelLieferungFilter: sammel_lieferung_bool_exp!) {\\n garten(where: $gartenFilter) {\\n id\\n __typename\\n }\\n art(where: $artFilter) {\\n id\\n __typename\\n }\\n event(where: $eventFilter) {\\n id\\n __typename\\n }\\n zaehlung(where: $zaehlungFilter) {\\n id\\n __typename\\n }\\n teilkultur(where: $teilkulturFilter) {\\n id\\n __typename\\n }\\n kultur(where: $kulturFilter) {\\n id\\n __typename\\n }\\n herkunft(where: $herkunftFilter) {\\n id\\n __typename\\n }\\n sammel_lieferung(where: $sammelLieferungFilter) {\\n id\\n __typename\\n }\\n lieferung(where: $lieferungFilter) {\\n id\\n __typename\\n }\\n person(where: $personFilter) {\\n id\\n __typename\\n }\\n sammlung(where: $sammlungFilter) {\\n id\\n __typename\\n }\\n}\\n\"}"
},
"http_info": {
"status": 200,
"http_version": "HTTP/1.1",
"url": "/v1/graphql",
"ip": "77.57.29.8:54377",
"method": "POST",
"content_encoding": null
}
}
}
If I instead set the type in the .env file of docker to RS256:
HASURA_GRAPHQL_JWT_SECRET={"type":"RS256", "jwk_url": "https://www.googleapis.com/service_accounts/v1/jwk/securetoken@system.gserviceaccount.com", "audience": "vermehrung-f48c4", "issuer": "https://securetoken.google.com/vermehrung-f48c4"}
the error is:
{
"type": "http-log",
"timestamp": "2020-03-10T13:20:10.808+0000",
"level": "error",
"detail": {
"operation": {
"error": {
"path": "$",
"error": "Could not verify JWT: JWSError JWSInvalidSignature",
"code": "invalid-jwt"
},
"request_id": "15985864-4e2f-4d35-b17d-1e061b96b67a",
"response_size": 94,
"raw_query": "{\"operationName\":\"TreeQueryForRoot\",\"variables\":{\"artFilter\":{\"id\":{\"_is_null\":false}},\"eventFilter\":{\"id\":{\"_is_null\":false}},\"gartenFilter\":{\"id\":{\"_is_null\":false},\"aktiv\":{\"_eq\":true}},\"kulturFilter\":{\"id\":{\"_is_null\":false},\"aktiv\":{\"_eq\":true}},\"herkunftFilter\":{\"id\":{\"_is_null\":false}},\"personFilter\":{\"id\":{\"_is_null\":false},\"aktiv\":{\"_eq\":true}},\"sammlungFilter\":{\"id\":{\"_is_null\":false}},\"lieferungFilter\":{\"id\":{\"_is_null\":false}},\"sammelLieferungFilter\":{\"id\":{\"_is_null\":false}},\"teilkulturFilter\":{\"id\":{\"_is_null\":false}},\"zaehlungFilter\":{\"id\":{\"_is_null\":false}}},\"query\":\"query TreeQueryForRoot($artFilter: art_bool_exp!, $eventFilter: event_bool_exp!, $gartenFilter: garten_bool_exp!, $kulturFilter: kultur_bool_exp!, $herkunftFilter: herkunft_bool_exp!, $personFilter: person_bool_exp!, $sammlungFilter: sammlung_bool_exp!, $teilkulturFilter: teilkultur_bool_exp!, $zaehlungFilter: zaehlung_bool_exp!, $lieferungFilter: lieferung_bool_exp!, $sammelLieferungFilter: sammel_lieferung_bool_exp!) {\\n garten(where: $gartenFilter) {\\n id\\n __typename\\n }\\n art(where: $artFilter) {\\n id\\n __typename\\n }\\n event(where: $eventFilter) {\\n id\\n __typename\\n }\\n zaehlung(where: $zaehlungFilter) {\\n id\\n __typename\\n }\\n teilkultur(where: $teilkulturFilter) {\\n id\\n __typename\\n }\\n kultur(where: $kulturFilter) {\\n id\\n __typename\\n }\\n herkunft(where: $herkunftFilter) {\\n id\\n __typename\\n }\\n sammel_lieferung(where: $sammelLieferungFilter) {\\n id\\n __typename\\n }\\n lieferung(where: $lieferungFilter) {\\n id\\n __typename\\n }\\n person(where: $personFilter) {\\n id\\n __typename\\n }\\n sammlung(where: $sammlungFilter) {\\n id\\n __typename\\n }\\n}\\n\"}"
},
"http_info": {
"status": 200,
"http_version": "HTTP/1.1",
"url": "/v1/graphql",
"ip": "77.57.29.8:57836",
"method": "POST",
"content_encoding": null
}
}
}
Could be related to https://github.com/hasura/graphql-engine/issues/3919 and https://github.com/hasura/graphql-engine/issues/3513.
What am I doing wrong?
Issue Analytics
- State:
- Created 4 years ago
- Comments:9
Top Results From Across the Web
Could not verify JWT: JWSError JWSInvalidSignature
I believe the issue involved mismatch access token secret key resulting in the error JWT: JWSError JWSInvalidSignature.
Read more >JWT (JSON Web Tokens) Errors | Invalid JWT Signature
I've been working with Google Cloud products and connecting to services from my laptop like Storage and BigQuery. Over the last several months, ......
Read more >Authentication using JWT | Hasura GraphQL Docs
Authentication using JWT. Introduction. You can configure the GraphQL engine to use JWT authorization mode to authorize all incoming requests to the Hasura ......
Read more >admin only operation firebase error - You.com | The AI Search ...
hasura/graphql-engine`JWSError JWSInvalidSignature`-Error on firebase#4076. Created almost 3 years ago. 9. I have a project using docker-compose:.
Read more >无法验证令牌签名, Jwt 无效签名, 签名验证失败jwt 流明, Laravel ...
签名验证失败· 问题#40 · firebase/php-jwt · GitHub问题是,即使第一个带有ROM ... 错误:无法验证JWT:JWSError JWSInvalidSignature Hasura “Hasura 平台利用JWT ...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
@dvasdekis
The project is here: https://github.com/barbalex/vermehrung
The backend is built with docker-compose and docker. You can see it here: https://github.com/barbalex/vermehrung/tree/master/backend
The backend:
api.vermehrung.ch/add-hasura-claims/{uid}
(https://github.com/barbalex/vermehrung/blob/master/backend/auth/server.js#L102).The app:
user.getIdToken(true)
(https://github.com/barbalex/vermehrung/blob/master/src/utils/setHasuraClaims.js#L21-L38). This token now contains the hasura claimsHope this helps.
I got same message, but It works well when I pass this token in Hasura console 😦