Postingan lainnya
Laravel 10 Sanctum with Next js 14 - Store dan akses token
jadi saya mau pisahin antara backend dan frontend tapi saya bingung di mana tempat yg aman untuk simpan token dari laravel setelah authentication, kemudian bagaimana implementasi protect route di next js nya ?
Untuk hal yg sudah saya lakukan:
1.setelah login, token kemudian saya simpan token di localStorage, dilanjut dengan redirect menggunakan ke halaman users (abaikan redirect menggunakan window.location.href)
//next js
// app/login/page.js
axios.get('http://localhost:8000/sanctum/csrf-cookie').then(response => {
axios({
url: "http://localhost:8000/api/auth/login",
method: "POST",
data: _this.serialize()
})
.then(res => {
if (res.status == 200) {
localStorage.setItem('token', JSON.stringify(res.data))
window.location.href = "http://localhost:3000/users"
} else {
toastr.error('', res.msg)
}
})
});
- di halaman Users, sebenarnya saya tetap ingin halaman sebagai server component, tapi dikarenakan saya harus menggunakan hook useEffect, untuk mengakses objct window dan localStorage, akhirnya saya tambahakan use client agar menjadi client component
//next js
// app/users/page.js
'use client'
import React, { useEffect } from 'react'
import UserLists from './_components/UserLists'
export default function users() {
useEffect(function () {
if (typeof window !== 'undefined' && window.localStorage) {
const token = localStorage.getItem('token')
if (token == null) window.location.href = "/login"
}
}, [])
return (
<>
<UserLists/>
</>
)
}
- sampai disini sebenernya secara fungsi sudah berjalan, tapi belum sempurna karena sebagian tampilan di halaman Users akan tetap ke render, sebelum diredirect ke halaman login ( jika token tidak ada)
saya minta bantuan dari master2 disini, saran atau mungkin punya cara yg lebih bagus untuk implementasi otentikasi seperti kasus saya ini dan mudah2an bahasa saya mudah untuk dimengerti , terima kasih
3 Jawaban:
Jawaban Terpilih
Secara umum, disarankan untuk menyimpan token pada cookies (httponly cookie)
ref:
- https://stackoverflow.com/questions/76086733/can-i-store-jwt-token-in-local-storage-while-using-next-js
- https://blog.logrocket.com/jwt-authentication-best-practices/
- https://www.linkedin.com/pulse/jwt-token-where-store-browser-deepak-jha/
Saya belum pernah bikin Nextjs client app untuk konsumsi JWT token, tapi sepertinya tempat yang tepat adalah middleware nya
ref:
- https://stackoverflow.com/questions/73431746/jwt-authentication-with-nextjs
- https://www.makeuseof.com/token-authentication-nextjs-using-jwt/
Tanggapan
Betul bang hilman, untuk konsumsi token dan protecting route lebih tepat di middleware supaya lebih terpusat, terima kasih bang hilman
Info tambahan, cookies pada nextjs: https://www.propelauth.com/post/cookies-in-next-js
Penyimpanan Token Menggunakan localStorage untuk menyimpan token memang praktis, tapi kurang aman dari serangan seperti Cross-Site Scripting (XSS). Sebagai alternatif, Anda bisa mempertimbangkan penggunaan HTTP Only Cookies. Laravel Sanctum menyediakan cara mudah untuk mengatur ini. Cookies HTTP Only tidak dapat diakses melalui JavaScript, yang meningkatkan keamanan.
- Protect Route di Next.js Menggunakan useEffect untuk redirect memang bekerja, tapi seperti yang Anda sebutkan, ada masalah dengan rendering. Ini bisa kita atasi dengan beberapa cara:
a. Server-Side Rendering (SSR) Anda bisa menggunakan getServerSideProps di Next.js untuk memeriksa token sebelum halaman dirender. Ini mencegah rendering halaman jika pengguna tidak terautentikasi.
Contoh kode:
export async function getServerSideProps(context) {
const token = context.req.cookies.token; // Asumsi token disimpan dalam cookie
if (!token) {
// Redirect jika tidak ada token
return {
redirect: {
destination: '/login',
permanent: false,
},
};
}
// Lanjutkan rendering halaman jika ada token
return { props: {} };
}
b. Client-Side dengan Custom Hook Anda bisa membuat custom hook untuk autentikasi di sisi klien. Hook ini akan menangani redirect dan kondisi token.
-
Menangani Token di Laravel Pastikan Anda mengatur middleware dan konfigurasi Sanctum dengan benar untuk menangani token dan sesi.
-
Konsiderasi Lain Refresh Token: Pertimbangkan implementasi refresh token untuk meningkatkan keamanan. Validasi Token: Pastikan token divalidasi di setiap request ke server.
Tanggapan
Terima kasih bang adam sudah membantu berikan jawaban.
Tapi setelah saya baca lagi dokumentasi next js, solusi dan bang adam lebih cocok untuk aplikasi next js yg menggunakan pages router
sedangkan saya menggunakan next js 13 dimana secara default menggunakan app router
tapi dengan bantuan instruksi dari bang adam, saya memakai beberapa logika dari jawaban bang adam yg bisa saya terapkan di app router ini
dan dengan adanya fitur middleware yg sepertinya baru ada di next 13 ini, sangat membantu sekali untuk sistem yg akan saya buat saat ini
Terima kasih banyak bang adam untuk jawaban dan penjelasan yg cukup jelas
untuk hasil kodingannya saya nanti akan share disini, siapa tau temen2 disini ada yg mengalami kasus yg sama
[UPDATE SNIPPET CODE] maaf telat banget share nya, tapi karena saya juga sudah janji jadi tetap saya bagikan
untuk di Laravelnya:
public function login(Request $request)
{
//validation process
$tokenCookie = cookie('token', $token);
return response($response)->cookie($tokenCookie); // langsung chain untuk create cookie yg berisi token
}
kemudian pada middleware.js di next seperti
export function middleware(request) {
let token = request.cookies.get('token') // untuk mendapatkan token
if (request.nextUrl.pathname.startsWith('/login')) {
if (token && token != "undefined") return NextResponse.redirect('http://localhost:3000/dashboard')
return NextResponse.next()
}
else {
if (token == undefined) return NextResponse.redirect('http://localhost:3000/login')
return NextResponse.next()
}
}
semoga cukup mudah untuk dipahami
sangat terbuka untuk saran agar bisa lebih baik kodenya dari segi security atau optimasi nya
sekian dan terima kasih
Tanggapan
terima kasih sudah sharing Naufal