47 Membuat Mutation Login dan Signup
Proses autentikasi user merupakan fondasi dari hampir semua aplikasi modern. Kemanan dan efisiensi dalam mengelola identitas pengguna sangat krusial, baik untuk aplikasi sederhana hingga yang kompleks. Pada artikel ke-47 dari serial ini, saya ingin membahas secara mendalam tentang bagaimana membangun mutation untuk Login dan Signup menggunakan GraphQL pada Node.js, lengkap dengan kode contoh, simulasi, dan diagram alur agar lebih mudah dipahami.
Mengapa Mutation?
Mutation dalam GraphQL digunakan untuk memodifikasi data di server, cocok untuk operasi seperti create (Signup) dan update (Login—biasanya untuk otentikasi). Dibandingkan REST API, pendekatan GraphQL membuat endpoint lebih elegan dan eksplisit. Ini sangat berguna saat aplikasi berkembang dan requirements bertambah kompleks.
Arsitektur Kasar
Sebelum masuk ke kode, mari kita pahami arsitekturnya secara garis besar:
- Frontend: Mengirim mutation
login
dansignup
ke backend. - Backend: Menyediakan Schema dan Resolver untuk mutation tersebut.
- Database: Menyimpan data user yang telah terenkripsi (password).
Mari kita ilustrasikan prosesnya dengan diagram alur berikut.
graph TD A[User] -->|Signup| B[GraphQL Mutation - signup] B --> C[Resolver] C --> D[Hash Password] D --> E[Store to Database] A2[User] -->|Login| F[GraphQL Mutation - login] F --> G[Resolver] G --> H[Verify Password] H --> I[Return JWT Token]
Desain Schema GraphQL
Mari mulai dengan mendesain schema dasar untuk mutation Login dan Signup.
type Mutation {
signup(username: String!, password: String!): AuthPayload!
login(username: String!, password: String!): AuthPayload!
}
type AuthPayload {
token: String
user: User
}
type User {
id: ID!
username: String!
}
Penjelasan:
signup
danlogin
mengembalikan objekAuthPayload
.AuthPayload
berisi JWT token dan data user.- Mutation menerima username dan password secara eksplisit.
Kode Implementasi pada Node.js
Tech Stack:
- Node.js
- Express.js
- Apollo Server (GraphQL)
- bcrypt (untuk hash password)
- jsonwebtoken (untuk generate JWT)
Misal kita sudah punya connection ke database MongoDB.
1. Model User (MongoDB/Mongoose)
// models/User.js
const mongoose = require('mongoose');
const userSchema = new mongoose.Schema({
username: { type: String, unique: true, required: true },
password: { type: String, required: true },
});
module.exports = mongoose.model('User', userSchema);
2. Implementasi Resolver
Mari lihat code logic untuk signup dan login.
// resolvers.js
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const User = require('./models/User');
const SECRET = 'MY_SUPER_SECRET_KEY';
const resolvers = {
Mutation: {
signup: async (_, { username, password }) => {
// Cek user sudah ada
const existingUser = await User.findOne({ username });
if (existingUser) {
throw new Error('Username has been taken');
}
// Hash password dengan bcrypt
const hashedPassword = await bcrypt.hash(password, 10);
// Create user baru
const user = new User({ username, password: hashedPassword });
await user.save();
// Generate JWT token
const token = jwt.sign(
{ userId: user.id, username: user.username },
SECRET,
{ expiresIn: '7d' }
);
return {
token,
user
};
},
login: async (_, { username, password }) => {
const user = await User.findOne({ username });
if (!user) {
throw new Error('User not found');
}
const valid = await bcrypt.compare(password, user.password);
if (!valid) {
throw new Error('Invalid password');
}
const token = jwt.sign(
{ userId: user.id, username: user.username },
SECRET,
{ expiresIn: '7d' }
);
return {
token,
user
};
}
}
};
module.exports = resolvers;
Simulasi Request dan Response
Mari kita lihat contoh request dan response nyata pada mutation ini.
1. Signup
Query
mutation {
signup(username: "johndoe", password: "supersecret") {
token
user {
id
username
}
}
}
Response
{
"data": {
"signup": {
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": {
"id": "649c22ebd58be255b9a38212",
"username": "johndoe"
}
}
}
}
2. Login
Query
mutation {
login(username: "johndoe", password: "supersecret") {
token
user {
id
username
}
}
}
Response
{
"data": {
"login": {
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": {
"id": "649c22ebd58be255b9a38212",
"username": "johndoe"
}
}
}
}
Perbandingan Mutation vs REST
Fitur | GraphQL Mutation | REST API |
---|---|---|
Endpoint | Satu endpoint “/graphql” | Banyak endpoint |
Response Data | Sesuai permintaan client | Fixed/terbatas |
Evolusi API | Mudah dikembangkan | Lebih rigid |
Error Handling | Konsisten via response GraphQL | Tergantung implementasi |
Best Practices
- Hash Password: Selalu hash password dengan
bcrypt
sebelum disimpan di database. - JWT Expiry: Sertakan expired date pada JWT token untuk keamanan.
- Error Message: Jangan tampilkan error message sensitif.
- Validasi Input: Gunakan validasi di sisi backend untuk username dan password.
- Rate-Limit & Lockout: Implementasikan rate limit pada endpoint login untuk mencegah brute-force.
Potensi Perluasan
Mutation ini adalah pondasi utama. Ada berbagai kemungkinan pengembangan:
- Reset Password
- Verifikasi Email
- Social Login
- Multi-Factor Authentication
Penutup
Membuat mutation login dan signup dengan GraphQL memang memberi banyak keunggulan: efisiensi, kemudahan ekspansi, dan kemanan lebih terstruktur. Kode yang bersih serta arsitektur yang jelas sangat mendukung skalabilitas aplikasi.
Jika Anda ingin memperkuat sistem autentikasi aplikasi, memahami dan mengimplementasikan dua mutation dasar ini adalah investasi yang sangat tepat. Selamat bereksperimen, jangan lupa tambahkan proteksi tambahan dan validasi pada langkah berikutnya!
Resource lebih lanjut:
69. Studi Kasus: Retry dan Backoff Strategy
Artikel Terhangat
50 Role-based Authorization di GraphQL
08 Aug 2025
72. Generate Swagger/OpenAPI dari Protobuf
08 Aug 2025
49 Autentikasi Resolver Berdasarkan Context
08 Aug 2025
48 Menyimpan dan Mengecek Token JWT
08 Aug 2025
Rental Mobil Kapasitas 7 Seat Bandung Murah
08 Aug 2025
47 Membuat Mutation Login dan Signup
08 Aug 2025

50 Role-based Authorization di GraphQL

72. Generate Swagger/OpenAPI dari Protobuf

49 Autentikasi Resolver Berdasarkan Context

48 Menyimpan dan Mengecek Token JWT

Rental Mobil Kapasitas 7 Seat Bandung Murah
