Giter VIP home page Giter VIP logo

elysia-jwt's Introduction

@elysiajs/static

Plugin for Elysia for using JWT Authentication.

Installation

bun add @elysiajs/jwt

Example

import { Elysia, t } from 'elysia';
import { jwt } from '@elysiajs/jwt';
import { cookie } from '@elysiajs/cookie';

const app = new Elysia()
  .use(
    jwt({
      name: 'jwt',
      // This should be Environment Variable
      secret: 'MY_SECRETS',
    })
  )
  .use(cookie())
  .get('/sign/:name', async ({ jwt, cookie, setCookie, params }) => {
    setCookie('auth', await jwt.sign(params), {
      httpOnly: true,
    });

    return `Sign in as ${params.name}`;
  })
  .get('/profile', async ({ jwt, set, cookie: { auth } }) => {
    const profile = await jwt.verify(auth);

    if (!profile) {
      set.status = 401;
      return 'Unauthorized';
    }

    return `Hello ${profile.name}`;
  })
  .listen(8080);

Config

This package extends jose, most config is inherited from Jose.

Below are configurable properties for using JWT plugin

name

Name to decorate method as:

For example, jwt will decorate Context with Context.jwt

secret

JWT secret key

schema

Type strict validation for JWT payload

Jose's config

Below is the config inherits from jose

alg

@default 'HS256'

Algorithm to sign JWT with

crit

Critical Header Parameter.

iss

JWT Issuer

@see RFC7519#section-4.1.1

sub

JWT Subject

@see RFC7519#section-4.1.2

aud

JWT Audience

@see RFC7519#section-4.1.3

jti

JWT ID

@see RFC7519#section-4.1.7

nbf

JWT Not Before

@see RFC7519#section-4.1.5

exp

JWT Expiration Time

@see RFC7519#section-4.1.4

iat

JWT Issued At

@see RFC7519#section-4.1.6

elysia-jwt's People

Contributors

bogeychan avatar deadlinecode avatar pan93412 avatar saltyaom avatar viliamkopecky avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

elysia-jwt's Issues

Adding scopes or Roles/permissions

I'm trying to use this plugin...but can't find a way or configuration that enable the use of scopes asigned to the generated JWT...is this possible ?

thanks for your help!

JWKS support

As jose supports JWKS for verification, it'd be great if this could too :)

Cant verify JWT for no reason

export const jwtAccessSetup = new Elysia()
.use(
  jwt({
    name: "jwtAccess",
    schema: t.Object({
        id: t.String(),
        role: t.String(),
        // ban: t.Boolean()
    }),
    secret: "I_have_many_random_words",
    exp: '1d',
  })
);
const accessToken = await jwtAccess.sign({ id: user.id, role: user.role || "user"})
const payload = await jwtAccess.verify(accessToken);
console.log(payload) => false

@elysiajs/jwt": "^1.0.2
Hi. My libriry was broken for some reason. I create jwt and immediately trying verify it and get false ..
изображение

is their any suggestions what i can do ? cause all authorization proccess is down right now

jwt.default is not a function

JWT not working after build:
ubuntu@ip-172-31-20-32:~/########/server$ pm2 logs 1
[TAILING] Tailing last 15 lines for [1] process (change the value with --lines option)
/home/ubuntu/.pm2/logs/######-server-out.log last 15 lines:
/home/ubuntu/.pm2/logs/######-server-error.log last 15 lines:
1|####### | Bun v1.1.8 (Linux x64)
1|####### | 102549 |
1|####### | 102550 | // src/plugins/jwt.ts
1|####### | 102551 | var jwt = __toESM(require_cjs6(), 1);
1|####### | 102552 | if (!process.env.SECRET_KEY)
1|####### | 102553 | throw new Error("SECRET not found");
1|####### | 102554 | var jwtPlugin = new Elysia().use(jwt.default({
1|####### | ^
1|####### | TypeError: jwt.default is not a function. (In 'jwt.default({
1|####### | name: "jwt",
1|####### | secret: process.env.SECRET_KEY
1|####### | })', 'jwt.default' is an instance of Object)
1|####### | at /home/ubuntu/######/server/build/index.js:102554:34
1|####### |
1|####### | Bun v1.1.8 (Linux x64)

My codes

import jwt from "@elysiajs/jwt";
import { Elysia } from "elysia";

if (!process.env.SECRET_KEY) throw new Error("SECRET not found");

const jwtPlugin = new Elysia().use(
  jwt({
    name: "jwt",
    secret: process.env.SECRET_KEY,
  })
);

export { jwtPlugin };

Script:

bun build ./src/index.ts --outdir ./build --target=node

Cannot pass entries from type JWTPayloadSpec into jwt.sign()

Problem: The argument morePayload of jwt.sign() is of type Record<string, string> & JWTPayloadSpec. This typing does not allow the field exp to be defined, among others, since JWTPayloadSpec defines their values as numbers, violating the Record<string, string> definition.

image

Property 'jwt' does not exists on context.

I am having trouble in using jwt property in routes in different files. Why is jwt not present although using functional callback?

app.ts

import jwt from "@elysiajs/jwt";
import Elysia from "elysia";
import { env } from "../env";
import { auth } from "./auth";

const app = new Elysia()
  .group("/api", (app) =>
    app
      .use(
        jwt({
          name: "jwt",
          secret: env.jwtSecret,
        }),
      )
      .use(auth),
  )
  .listen(8080);
console.log(
  `🦊 Elysia is running at ${app.server?.hostname}:${app.server?.port}`,
);

auth.ts

import Elysia from "elysia";

export const auth = (app: Elysia) => app.get("/auth", ({ jwt }) => "auth");
// Property 'jwt' does not exists on type...

schema: t.String() error

изображение

export const jwtMessaging2 = new Elysia()
.use(
  jwt({
    name: "jwtMessaging",
    schema: t.String(),
    secret: "wkihfijbwnijoenfiwb euifbui23g89rg82g38r bdui293neruer 23u9br8ui923h8i",
    exp: '2h',
  })
);
export const messageEncrypt2 = (app: Elysia) =>
  app
    .use(jwtMessaging)
    .guard({response: t.String()})
    .onAfterHandle(async ({ jwtMessaging, response }) => {
        const payloadMessage = await jwtMessaging.sign(response);
        return payloadMessage;
    })

Hi! For some reason i cannt make schema that should be only as string. Its not correct or its a bug ?
@elysiajs/jwt": "^1.0.2"

Feat: expired token should still return content

When i do jwt.verify and token is expired i only get false returned, but when is not expired i get the token payload.

Would be really nice if its expired to still return the payload.
Maybe:

{
  "payload": {},
  "status": false
}

The return type of jwt doesn't seem to work properly in version 0.7.1.

Nice to meet you. I am a Korean preparing to become a developer.
We apologize for the inconvenience caused by raising the issue through a translator and ask for your understanding.

I am developing a personal blog through elysia with bun, and while using the @elysiajs/jwt^0.7.1 module, the name set in jwt is not properly entered into the decorate of the context.

Please check this issue and let me know the solution.

+++ It seems to work normally in version 0.6.1.

Jwt verify problems

Hello guys, i got a problem with the .verify method of the @elysia/jwt package.
I'm trying to verify my jwt token but it doesn't work and return false.
jwt.io tell me there is nothing wrong with my token

here is my code:

  const jwt = await jwtAccess.verify(cookie!.access_token);
  console.log("Test verify JWT", jwt, cookie!.access_token);
  if (!jwt) {
    set.status = 401;
    return {
      success: false,
      message: "Unauthorized",
      errors: "Invalid access token",
    };
  }

this code is in a middleware, and the cookie is set in the request.
the code of the jwtAccess.verify method is:

export const jwtAccessSetup = new Elysia({
  name: "jwtAccess",
}).use(
  jwt({
    name: "jwtAccess",
    schema: t.Object({
      userId: t.String(),
    }),
    secret: process.env.JWT_ACCESS_SECRET || "DO NOT USE THIS SECRET KEY",
    exp: 30 * 24 * 60 * 60,
  })
);

Even this, return false

const test = await jwtAccess.sign({ userId: "652e83d3b47c67a8d823daa6" });
console.log("@Cookie verify", await jwtAccess.verify(test));

every time i want to check the jwt, it returns me false but when i check it with the jwt.io debugger, it works.
is there a problem with the verify method or am i doing something wrong?

full repo: https://github.com/ImJustLucas/bun-elysia-boilerplate/tree/master

Header Parameter is stored in the payload instead of header

The Header Parameter config according to https://elysiajs.com/plugins/jwt.html#config is being stored in the payload section instead of header

for example, when doing

// setup.ts
export const JWT = jwt({
	name: "jwt",
	secret: "supersecret",
	typ: "JWT",
});

// main.ts
const jwtResult = await jwt.sign({
        sub: "subject",
});

will result in

eyJhbGciOiJIUzI1NiJ9.eyJ0eXAiOiJKV1QiLCJzdWIiOiJzdWJqZWN0In0.f69kq3ejRaV56IDJOAKDKHlejLU6_MiSiKsa5U4nTIs
{
  "alg": "HS256"
}
{
  "typ": "JWT",
  "sub": "subject"
}

instead of

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJzdWJqZWN0In0.aaT9AYvX_t5IExIkcUJ6Ux38zJcZ89-7q8SNlG5P9dM
{
  "alg": "HS256",
  "typ": "JWT"
}
{
  "sub": "subject"
}

looking at the code it seems there's no differentiation which is payload and which is header except the alg and crit

elysia-jwt/src/index.ts

Lines 136 to 144 in 188b20c

let jwt = new SignJWT({
...payload,
...morePayload,
nbf: undefined,
exp: undefined
}).setProtectedHeader({
alg,
crit
})

JWT secret accepts string, EdDSA keys require type CryptoKey for signing

TypeError: Key for the EdDSA algorithm must be of type CryptoKey. Received an instance of Uint8Array

Replicability:

jwt({
      alg: "EdDSA",
      // both have errors
      secret: (await readPrivateKey()), // returns CryptoKey
      // secret: readPrivateKeyToString() // returns string
})
// ...
jwt.sign({}) // error here

Version:
"@elysiajs/jwt": "^0.6.3"

Not able to pass exp to sign function

It would be nice to be able to pass custom expiration times when generating new tokens (a gateway app that generates tokens for multiple APIs, for example).

Current:

if (exp)
    jwt = jwt.setExpirationTime(exp);

Suggestion:

if (exp ?? morePayload.exp)
    jwt = jwt.setExpirationTime(morePayload.exp ?? exp);

That way the provided expiration time overrides the default expiration time defined in the constructor, if provided.

Example:

import { Elysia } from 'elysia';
import { jwt } from '@elysiajs/jwt';

const app = new Elysia();

// Default JWT expiration is 1 hour.
app.use(jwt({ name: 'jwt', secret: Bun.env.MY_JWT_SECRET!, exp: '1hr' }));

app.get('/sign/:name', async (context: any) => {
  // Default, 1 hour expiration.
  context.setCookie('auth', await context.jwt.sign(context.params), {
    httpOnly: true,
  });

  return `Sign in as ${context.params.name}`;
});

app.get('/sign-longer/:name', async (context: any) => {
  // 24 hour expiration.
  context.setCookie('auth', await context.jwt.sign({ ...context.params, exp: '24hr' }), {
    httpOnly: true,
  });

  return `Sign in as ${context.params.name}`;
});

app.listen(3000);
console.log(
  `🦊 Elysia is running at ${app.server?.hostname}:${app.server?.port}`
);

@elysiajs/jwt ^1.0.2 breaks type inference for handler functions

I added @elysiajs/jwt ^1.0.2 to my project and initialised it with the .use hook. Everything seems to work fine however it breaks the type inference causing the handler method parameters to implicitly return a type of any.

    app.use(jwt({
        secret: env.JWT_SECRET,
        algorithms: ["HS256"],
        maxAge: "1d",
        clockTolerance: 0
    }))
    .get("/", async ({query, jwt, set, cookie: { auth }}) => {
            const verified = await jwt.verify(auth.value)
            if (!verified) {
                set.status = 401
                return 'Unauthorized'
            }
            const users = await AuthenticationController.all(query);
            return ApiResponse.success(users);
        },
        {
            detail: { tags: ["Authentication"] }
        }
    )

jwt, query, set, and auth now implicitly have the type of any

Support `Cloudflare`

The following code doesn't work on Cloudflare because dynamic is false

const jwtType = t.Object({
  id: t.Number(),
});

export const authPlugin = new Elysia({ name: "authPlugin" }).use(
  jwt({
    secret: "yay",
    name: "jwt",
    exp: "20m",
    schema: jwtType,
  })
);

This function call missing dynamic parameter:

? getSchemaValidator(

Cloudflare error:

EvalError: Code generation from strings disallowed for this context

reported on discord

CryptoKey instances for asymmetric algorithm verifying must be of type "public"

I am using the following jwt setup

export const jwt = jwtPlugin({
  name: 'jwt',
  alg: 'EdDSA',
  exp: '30m',
  schema: user,
  secret: await importJWK(
    {
      crv: 'Ed25519',
      d: 'N3cOzsFZwiIbtNiBYQP9bcbcTIdkITC8a4iRslrbW7Q',
      x: 'RjnTe-mqZcVls6SQ5CgW0X__jRaa-Quj5HBDREzVLhc',
      kty: 'OKP',
    },
    'EdDSA',
  ),
})

This works for signing, but not for verification

TypeError: CryptoKey instances for asymmetric algorithm verifying must be of type "public"

It's worth noting that @elysia/jwt is using version 4 of jose. It might be a good idea to consider upgrading to version 5.

bug sign args exp type

jwt.sign exp type = number | undefined

jwt.sign exp is of type number | undefined

and jose takes number | string | Date

image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.