Skip to content

Commit

Permalink
chore: 불필요한 컬럼 제거 및 session_sid 추가
Browse files Browse the repository at this point in the history
  • Loading branch information
Xvezda committed Apr 27, 2024
1 parent 7fc5697 commit 00886ef
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 62 deletions.
4 changes: 0 additions & 4 deletions apps/api/src/db/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,6 @@ export const users = sqliteTable('users', {
userImage: text('user_image'),
createdAt: integer('created_at', { mode: 'timestamp_ms' }).notNull(),
updatedAt: integer('updated_at', { mode: 'timestamp_ms' }).notNull(),
accessToken: text('access_token'),
refreshToken: text('refresh_token'),
tokenType: text('token_type'),
expireAt: integer('expire_at', { mode: 'timestamp_ms' }),
}, (table) => {
return {
idxUserId: uniqueIndex('idx_users_user_id').on(table.userId),
Expand Down
133 changes: 75 additions & 58 deletions apps/api/src/services/auth/v1/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,12 @@ type SessionPayload = PrefixRoot<typeof JWT_PREFIX, {
userName: string;
userImage: string;
accessToken: string;
tokenType: string;
expireAt: Date;
updatedAt: Date;
};
}>;

type SecuredSessionPayload = PrefixRoot<typeof JWT_PREFIX, {
user: {
refreshToken: string;
};
}>;

Expand Down Expand Up @@ -110,7 +113,7 @@ const withPrevUrl: MiddlewareHandler<{

const stateCookie = getCookie(c, 'state');
if (stateCookie) {
const jwt = await jose.compactDecrypt(getCookie(c, 'state')!, c.var.privateKey);
const jwt = await jose.compactDecrypt(stateCookie, c.var.privateKey);
const payload = await verifyToken<StatePayload>(c, jwt.plaintext);

prevUrl = payload['http:cheda.kr/state'].url;
Expand Down Expand Up @@ -176,18 +179,23 @@ const withSession: MiddlewareHandler<{

try {
const sessionId = getCookie(c, 'session_id');
if (!sessionId) throw new InvalidToken();
const sessionSid = getCookie(c, 'session_sid');
if (!sessionId || !sessionSid) throw new InvalidToken();

const payload = await verifyToken<SessionPayload>(c, sessionId);
const user = payload['http:cheda.kr/user'];
let user = payload['http:cheda.kr/user'];

const threshold = 1000 * 60 * 10;
if (new Date(user.expireAt).getTime() <= Date.now() + threshold) {
if (new Date(payload.exp! * 1000).getTime() <= Date.now() + threshold) {
const securedToken = await decryptToken(c, sessionSid);
const securedPayload = await verifyToken<SecuredSessionPayload>(c, securedToken);
const { refreshToken } = securedPayload['http:cheda.kr/user'];

const url = new URL('https://nid.naver.com/oauth2.0/token');
url.searchParams.append('grant_type', 'refresh_token');
url.searchParams.append('client_id', c.env.OAUTH_CLIENT_ID_NAVER);
url.searchParams.append('client_secret', c.env.OAUTH_CLIENT_SECRET_NAVER);
url.searchParams.append('refresh_token', user.refreshToken);
url.searchParams.append('refresh_token', refreshToken);

const response = await fetch(url);
const result = await response.json() as RefreshTokenResponse;
Expand All @@ -201,32 +209,31 @@ const withSession: MiddlewareHandler<{
fetch('https://openapi.naver.com/v1/nid/verify?info=true', { headers }).then(r => r.json()) as Promise<NidVerifyResponse>
]);

const userPatch = {
user = {
userId: meResult.response.id,
userName: meResult.response.nickname,
userImage: meResult.response.profile_image,
accessToken: result.access_token,
tokenType: result.token_type,
expireAt: new Date(verifyResult.response.expire_date),
updatedAt: new Date(),
};
const expires = new Date(verifyResult.response.expire_date);

const db = drizzle(c.env.DB);
await db.update(usersTable)
.set(userPatch)
.where(eq(usersTable.userId, meResult.response.id));

const expires = new Date(Date.now() + parseInt(result.expires_in) * 1000);
const jwt = await signToken(c, { ...user, ...userPatch }, expires);
const session = await signToken(
c,
prefixRoot(JWT_PREFIX, {
user,
}) satisfies SessionPayload,
expires
);

setCookie(c, 'session_id', jwt, {
setCookie(c, 'session_id', session, {
expires,
...c.env.DEV ? {} : {
secure: true,
domain: '.cheda.kr',
},
});
}
c.set('session', { user: payload['http:cheda.kr/user'] });
c.set('session', { user });
} catch (e) {
if (e instanceof InvalidToken) {
deleteCookie(c, 'session_id');
Expand Down Expand Up @@ -263,10 +270,6 @@ app.get('/logout', withPrevUrl, async (c) => {
if (!sessionId) {
return c.redirect(c.var.prevUrl);
}

const payload = await verifyToken<SessionPayload>(c, sessionId);
const user = payload['http:cheda.kr/user'];

/*
const url = new URL('https://nid.naver.com/oauth2.0/token');
url.searchParams.append('grant_type', 'delete');
Expand All @@ -279,15 +282,6 @@ app.get('/logout', withPrevUrl, async (c) => {
const result = await response.json() as DeleteTokenRespone;
*/

const db = drizzle(c.env.DB);
await db.update(usersTable)
.set({
accessToken: null,
expireAt: null,
updatedAt: new Date(),
})
.where(eq(usersTable.userId, user.userId));

deleteCookie(c, 'session_id');

return c.redirect(c.var.prevUrl);
Expand Down Expand Up @@ -377,52 +371,75 @@ app.get('/callback', async (c) => {
fetch('https://openapi.naver.com/v1/nid/verify?info=true', { headers }).then(r => r.json()) as Promise<NidVerifyResponse>
]);

const db = drizzle(c.env.DB);

const now = new Date();
const user = {
userId: meResult.response.id,
userName: meResult.response.nickname,
userImage: meResult.response.profile_image,
createdAt: new Date(),
updatedAt: new Date(),
createdAt: now,
updatedAt: now,
accessToken: result.access_token,
refreshToken: result.refresh_token,
tokenType: result.token_type,
expireAt: new Date(verifyResult.response.expire_date),
};
const expires = new Date(verifyResult.response.expire_date);

const db = drizzle(c.env.DB);
try {
await db.insert(usersTable)
.values(user);
.values({
userId: meResult.response.id,
userName: meResult.response.nickname,
userImage: meResult.response.profile_image,
createdAt: now,
updatedAt: now,
});
} catch (e) {
await db.update(usersTable)
.set({
userName: meResult.response.nickname,
userImage: meResult.response.profile_image,
updatedAt: now,
})
.where(eq(usersTable.userId, user.userId));
}

const session = await signToken(
c,
prefixRoot(JWT_PREFIX, {
user: {
userId: user.userId,
userName: user.userName,
userImage: user.userImage,
accessToken: user.accessToken,
},
}) satisfies SessionPayload,
expires
);

const weekLater = new Date(Date.now() + 1000 * 60 * 60 * 24 * 7);
let securedSession = await signToken(
c,
prefixRoot(JWT_PREFIX, {
user: {
refreshToken: user.refreshToken,
tokenType: user.tokenType,
expireAt: user.expireAt,
updatedAt: user.updatedAt,
})
.where(eq(usersTable.userId, user.userId));
}
},
}) satisfies SecuredSessionPayload,
weekLater,
);
securedSession = await encryptToken(c, securedSession);

const payload = prefixRoot(JWT_PREFIX, {
user: {
userId: user.userId,
userName: user.userName,
userImage: user.userImage,
accessToken: user.accessToken,
expireAt: user.expireAt,
updatedAt: user.updatedAt,
setCookie(c, 'session_id', session, {
expires,
...c.env.DEV ? {} : {
secure: true,
domain: '.cheda.kr',
},
});

const jwt = await signToken(c, payload, user.expireAt);

setCookie(c, 'session_id', jwt, {
expires: new Date(Date.now() + parseInt(result.expires_in) * 1000),
setCookie(c, 'session_sid', securedSession, {
httpOnly: true,
expires,
...c.env.DEV ? {} : {
secure: true,
domain: '.cheda.kr',
Expand Down

0 comments on commit 00886ef

Please sign in to comment.