-
Notifications
You must be signed in to change notification settings - Fork 3
Feature/43 jwt #67
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Feature/43 jwt #67
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| module.exports = { | ||
| semi: false, | ||
| singleQuote: true, | ||
| trailingComma: 'all', | ||
| } |
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| import axios from 'axios'; | ||
| import { NextResponse } from 'next/server'; | ||
| import { verifyJwt } from '@/app/lib/jwt'; | ||
|
|
||
| interface reqBody { | ||
| text: string; | ||
| } | ||
| type resBody = { | ||
| result: string; | ||
| } | ||
|
|
||
| export const POST = async(req: Request) => { | ||
| const body: reqBody = await req.json(); | ||
| const accessToken = req.headers.get('Authorization')?.split('mlru ')[1] as string; | ||
|
|
||
| // 헤더에 토큰이 없거나, 토큰 복호화 실패하면 리턴. | ||
| if(!accessToken || !verifyJwt(accessToken)) { | ||
| return new Response(JSON.stringify({"result":"No Authorization"})) | ||
| } | ||
| try { | ||
| const res = await axios.post(`${process.env.MODEL_URL}/advice/`,{ | ||
| text: body.text | ||
| }); | ||
| const result = res.data | ||
| return NextResponse.json(result.result) | ||
| } catch (err) { | ||
| console.log(err) | ||
| return NextResponse.json(err) | ||
| } | ||
|
|
||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,174 @@ | ||
| import { NextRequest, NextResponse } from "next/server"; | ||
| import axios from 'axios'; | ||
| import queryPromise from "@/app/lib/db"; | ||
| export const api = { | ||
| bodyParse: false | ||
| }; | ||
|
|
||
| // POST 작성 | ||
| // PATCH 수정 | ||
| // DELETE 삭제 | ||
|
|
||
| export async function POST( req: NextRequest, res: NextResponse ) { | ||
| const data = await req.formData(); | ||
| const accessToken = req.headers.get('Authorization')?.split('mlru ')[1] as string; | ||
| const title = data.get('title') as string; | ||
| const content = data.get('content') as string; | ||
| const weather = data.get('weather') as string; | ||
| const id = data.get('id') as string; | ||
| const name = data.get('name') as string; | ||
| const imgTit = data.get('imgTit') as string; | ||
|
|
||
|
|
||
| const predictEmo = await axios.post( | ||
| `${process.env.BASE_URL}/api/emotion`, | ||
| {text: content}, | ||
| { | ||
| headers: { | ||
| 'Authorization': `mlru ${accessToken}` | ||
| } | ||
| } | ||
| ); | ||
| console.log(predictEmo.data); // 감정 숫자. | ||
|
|
||
| const maxEmotion = Object.entries(predictEmo.data).reduce((max: any, [key, value]: any) => { | ||
| return value > max[1] ? [key, value] : max; | ||
| }, ['', -Infinity]); | ||
|
|
||
| const predictSumm = await axios.post( | ||
| `${process.env.BASE_URL}/api/summary`, | ||
| {text: content}, | ||
| { | ||
| headers: { | ||
| 'Authorization': `mlru ${accessToken}` | ||
| } | ||
| } | ||
| ); | ||
|
|
||
| console.log(predictSumm.data); // 내용 요약. | ||
|
|
||
| const predictAdvice = await axios.post( | ||
| `${process.env.BASE_URL}/api/advice`, | ||
| {text:predictSumm.data}, | ||
| { | ||
| headers: { | ||
| 'Authorization': `mlru ${accessToken}` | ||
| } | ||
| } | ||
| ); | ||
| console.log(predictAdvice.data); // 조언 | ||
|
|
||
| const weatherQuery: { [key: string]: string } = { | ||
| "맑음": "sunny", | ||
| "흐림":"cloudy", | ||
| "비":"rainy", | ||
| "바람":"windy", | ||
| "눈":"snowy" | ||
| }; | ||
| const emotionQuery: { [key: string]: string } = { | ||
| "중립": "normal", | ||
| "슬픔": "sadness", | ||
| "분노": "angry", | ||
| "놀람": "amazing", | ||
| "행복": "happiness", | ||
| "불안": "unhappiness" | ||
| }; | ||
| const query = 'weather is ' + weatherQuery[weather] + `, feel ${emotionQuery[maxEmotion[0]]} in the picture`; | ||
| let imgSrc = []; | ||
| const predictImg = await axios.post( | ||
| `${process.env.BASE_URL}/api/img`, | ||
| {text: query}, | ||
| { | ||
| headers: { | ||
| 'Authorization': `mlru ${accessToken}` | ||
| } | ||
| } | ||
| ); | ||
| imgSrc.push(predictImg.data.result); | ||
| const img = data.get('img') as File; | ||
| if(img) { | ||
| const fb = new FormData(); | ||
| fb.append('image', img); | ||
| const result = await axios.post( | ||
| 'https://api.imgur.com/3/upload', | ||
| fb, | ||
| { | ||
| headers: { | ||
| 'Authorization': `Client-ID ${process.env.IMGUR_KEY}`, | ||
| 'Accept': 'application/json' | ||
| } | ||
| } | ||
| ); | ||
| imgSrc.push(result.data.data.link); | ||
| } | ||
|
|
||
| try { | ||
| let sql = 'INSERT INTO tb_diary VALUES(?,?,?,?,?,?,?,?,?,?,?,?)'; | ||
| let values = [ | ||
| null, | ||
| id, | ||
| name, | ||
| title, | ||
| content, | ||
| predictEmo.data, | ||
| weather, | ||
| 'pretendard', | ||
| null, | ||
| predictAdvice.data, | ||
| new Date(), | ||
| new Date() | ||
| ]; | ||
| const result = await queryPromise(sql, values); | ||
| if(img) { | ||
| sql = 'INSERT INTO tb_image VALUES(?,?,?,?,?,?)'; | ||
| values = [null, result.insertId, imgTit, imgSrc, 'user', new Date()]; | ||
| const done = await queryPromise(sql, values); | ||
| } | ||
| return NextResponse.json({result:'done'}); | ||
| } catch (err) { | ||
| console.log(err); | ||
| return NextResponse.json({result:'error'}) | ||
|
Comment on lines
+12
to
+130
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| } | ||
| }; | ||
|
|
||
| export const PUT = async(req: Request) => { | ||
| const data = await req.formData(); | ||
| const images: any[] = []; | ||
| data.forEach((v, k) => { | ||
| images.push(v); | ||
| }) | ||
| const imgs: any[] = []; | ||
|
|
||
| const uploadImages = async () => { | ||
| for (const v of images) { | ||
| const fb = new FormData(); | ||
| fb.append('image', v); | ||
|
|
||
| try { | ||
| const result = await axios.post( | ||
| 'https://api.imgur.com/3/upload', | ||
| fb, | ||
| { | ||
| headers: { | ||
| 'Authorization': `Client-ID ${process.env.IMGUR_KEY}`, | ||
| 'Accept': 'application/json' | ||
| } | ||
| } | ||
| ); | ||
| imgs.push(result.data.data.link); | ||
| } catch (error) { | ||
| console.log(error); | ||
| return 0; | ||
| } | ||
| } | ||
| return imgs; | ||
| }; | ||
|
|
||
| const result = await uploadImages(); | ||
| if(result === 0) { | ||
| return NextResponse.json({result:'error'}); | ||
| } | ||
| console.log(result); | ||
|
|
||
| return NextResponse.json({result:imgs}) | ||
| } | ||
|
Comment on lines
+134
to
+174
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,7 +4,7 @@ import { verifyJwt } from '@/app/lib/jwt'; | |
|
|
||
|
|
||
| type reqBody = { | ||
| text: string; | ||
| text: string[]; | ||
| } | ||
| type resBody = { | ||
| result: string; | ||
|
Comment on lines
4
to
10
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Error handling in the catch block could be improved by returning a more informative error response to the client. Currently, it returns the error object directly, which might expose sensitive information or be uninformative. Consider returning a standardized error message and logging the detailed error server-side. - console.log(err)
- return NextResponse.json(err)
+ console.error(err);
+ return new Response(JSON.stringify({ "error": "An error occurred while processing your request." }), { status: 500 }); |
||
|
|
@@ -19,7 +19,7 @@ export async function POST (req: Request) { | |
| return new Response(JSON.stringify({"result":"No Authorization"})) | ||
| } | ||
| try { | ||
| const res = await axios.post(`http://127.0.0.1:8000/predict/emotion/`,{ | ||
| const res = await axios.post(`${process.env.MODEL_URL}/emotion/`,{ | ||
| text: body.text | ||
| }); | ||
| const result: resBody = res.data | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -1,5 +1,6 @@ | ||||||
| import { signJwtAccessToken, signJwtRefreshToken } from '@/app/lib/jwt' | ||||||
| import queryPromise from '@/app/lib/db' | ||||||
| import { NextResponse } from 'next/server'; | ||||||
| const crypto = require('crypto'); | ||||||
|
|
||||||
| interface reqBody { | ||||||
|
|
@@ -10,9 +11,8 @@ interface reqBody { | |||||
| export const POST = async(req: Request) => { | ||||||
| const body: reqBody = await req.json(); | ||||||
| let sql = 'SELECT user_id, user_password, user_name, user_salt FROM tb_user WHERE user_id = ?'; | ||||||
| let values = [body.username]; | ||||||
| let result = await queryPromise(sql, values); | ||||||
| if(result.length < 1) return new Response(JSON.stringify({"result":"no user"})); | ||||||
| let result = await queryPromise(sql, [body.username]); | ||||||
| if(result.length < 1) return NextResponse.json({result:'아이디가 없습니다.'}) | ||||||
| const hashPassword = crypto.createHash('sha512').update(body.password + result[0].user_salt).digest('hex'); | ||||||
| const chk = hashPassword === result[0].user_password; | ||||||
| if(chk) { | ||||||
|
|
@@ -28,5 +28,5 @@ export const POST = async(req: Request) => { | |||||
| refreshToken | ||||||
| }; | ||||||
| return new Response(JSON.stringify(rst)) | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The response for a successful login attempt should also use - return new Response(JSON.stringify(rst))
+ return NextResponse.json(rst)Commitable suggestion
Suggested change
|
||||||
| } else return new Response("Wrong Password"); | ||||||
| } else return NextResponse.json({result:'비밀번호가 일치하지 않습니다.'}) | ||||||
| } | ||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -24,10 +24,10 @@ export async function POST(req: Request) { | |||||||||||||||||||||||||||||||||||||||||||||
| `; | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| // 쿼리 실행 | ||||||||||||||||||||||||||||||||||||||||||||||
| await queryPromise(sql, [user_id, emotion_img, user_pw, user_name, provider]); | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| const result = await queryPromise(sql, [user_id, emotion_img, user_pw, user_name, provider]); | ||||||||||||||||||||||||||||||||||||||||||||||
| console.log('test------------------------') | ||||||||||||||||||||||||||||||||||||||||||||||
| // 성공적인 응답 반환 | ||||||||||||||||||||||||||||||||||||||||||||||
| const result = { emotion_img }; | ||||||||||||||||||||||||||||||||||||||||||||||
| console.log(result); | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| // NextResponse 생성자를 사용하여 응답 반환 | ||||||||||||||||||||||||||||||||||||||||||||||
| return new NextResponse(JSON.stringify(result), { | ||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
24
to
33
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The code correctly logs the result of the database query. However, it's generally not a good practice to leave console logs in production code as it can lead to unintentional information disclosure and clutter the server logs. Consider removing the console log or using a more sophisticated logging mechanism that can be toggled for development and production environments. - console.log('test------------------------')
- console.log(result);Commitable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Authorizationheader is not correctly splitting the token. It seems to be looking for the string'mlru 'which might be a typo or a specific token prefix. Verify that this is the intended prefix and not the standard'Bearer '.Responseobject, not aNextResponseobject. For consistency, consider usingNextResponsefor all responses.POSTfunction should explicitly set the response content type toapplication/jsonwhen returning JSON data.POSTfunction is not setting an appropriate HTTP status code when the JWT token is missing or invalid. It should return a401 Unauthorizedstatus code in such cases.POSTfunction is not setting an appropriate HTTP status code for errors caught in the catch block. It should return a500 Internal Server Errorstatus code for unexpected errors.Commitable suggestion