In an online exam system, security is not just a feature, but a foundation. The system must ensure that:
- Users accessing the system are indeed legitimate users (authentication)
- Each user can only access features according to their role (authorization)
Without proper authentication and authorization mechanisms, the entire database design and exam features built in the previous chapter become vulnerable.
In this chapter, we will discuss the authentication approach used in Academic Suite, the reasons for technology selection, and the implementation patterns used to secure system access.
3.1 Authentication Approach in Academic Suite
Academic Suite uses a stateless authentication approach with JSON Web Token (JWT).
Unlike session-based authentication which stores login status in server memory or Redis, JWT stores user information directly inside the token sent by the client with every request.
This approach was chosen because it is more suitable for an online exam system that has the following characteristics:
- High request volume
- Many users active simultaneously
- Need for horizontal scalability
3.2 Why JWT (JSON Web Token)?
JWT provides several important advantages for the context of an online exam system:
Scalability
Token validation does not require a database query on every request. The server simply verifies the token signature, keeping the database load controlled even when thousands of students are active simultaneously.Stateless
The server does not need to store session state, making the application easier to scale horizontally.Mobile Ready
JWT is easy to use on web applications as well as mobile applications, opening up future client development opportunities.
This approach is also consistent with the separated frontend–backend architecture used by Academic Suite.
3.3 Authentication Flow
The login process is implemented on the backend, specifically in the file backend/handlers/auth.go.
Broadly speaking, the login flow is as follows:
Request
The client sends credentials in the form of{ email, password }in JSON format.User Lookup
The server searches for user data based on email in the database.Password Verification
The password sent is verified against the stored hash.Token Generation
If valid, the server generates a JWT containing user information (claims) and returns it to the client.
This token is then included by the client in every subsequent request.
Password Security with Bcrypt
Academic Suite never stores passwords in plain-text. For password hashing, bcrypt is used with a relatively high cost.
// During registration or data seeding
hashed, _ := bcrypt.GenerateFromPassword([]byte("password123"), 14)
// During login
err := bcrypt.CompareHashAndPassword(
[]byte(user.Password),
[]byte(inputPassword),
)
Using bcrypt ensures that even if the database is leaked, the user's original password remains difficult to reconstruct.
3.4 Anatomy of JWT & Claims
The JWT generated by the system contains important data in the claims section.
claims := jwt.MapClaims{
"userId": user.ID,
"role": user.Role, // admin, teacher, student
"exp": time.Now().Add(time.Hour * 1).Unix(),
}
Information stored in the token includes:
-
userIdfor user identification -
rolefor authorization needs -
expas the token validity time limit
By including the role inside the token, the system can check access rights without needing to query the users table on every request.
3.5 Authentication Middleware
To protect API endpoints, Academic Suite uses authentication middleware.
This middleware is responsible for:
- Retrieving the
Authorization: Bearer <token>header from the request - Verifying the JWT signature using the secret key
- Extracting
userIdandroledata - Storing that data into the request context
Example code snippet:
c.Locals("userId", claims["userId"])
c.Locals("role", claims["role"])
return c.Next()
With this approach, handlers in the next layer can access user information without thinking about re-authentication details.
3.6 Role-Based Access Control (RBAC)
Authentication ensures who the user is, but authorization determines what that user is allowed to do.
Academic Suite implements Role-Based Access Control (RBAC) with three main roles:
-
admin -
teacher -
student
For example, only teacher and admin are allowed to create or manage quizzes.
Example role check pattern in a handler:
func CreateQuiz(c *fiber.Ctx) error {
role := c.Locals("role").(string)
if role != "teacher" && role != "admin" {
return c.Status(403).JSON(fiber.Map{
"error": "Forbidden",
})
}
// Quiz creation logic
}
This approach is simple yet effective for a system with limited and clear roles.
3.7 Security Notes for Production
Several important things to consider before the system is used in a production environment:
-
jwtSecretmust not be hardcoded in the source code - Use environment variables (
JWT_SECRET) to store the secret key - Set token validity (
exp) according to security needs - Consider a token refresh mechanism if session duration is extended
These steps are crucial to preventing token misuse and maintaining overall system security.
Chapter Summary
In this chapter, we have built the foundation of Academic Suite security through a JWT-based authentication system and a role-based authorization mechanism.
With solid authentication and authorization, we can ensure that every system feature can only be accessed by authorized users.
In Chapter 4, we will begin to enter the functional core of the LMS: quiz management and question bank, which serves as the basis for the entire online exam process.
Top comments (0)