KAHIBARO
Discord Login Register

13.1. Authentication vs Authorization

Understanding Identity and Access

Backend systems constantly answer two questions:

  1. Who are you?
  2. What are you allowed to do?

These are the core ideas behind authentication and authorization. They always work together, but they solve different problems and use different mechanisms. As a backend developer you must keep them clearly separated in your mind and in your code.

In this chapter you will learn:

What Is Authentication?

Authentication is about proving identity.

When a user or system connects to your backend, the backend needs to know who is making the request. Authentication is the process that answers that question.

Common ways to authenticate:

MethodExample
Password basedEmail + password login form
Token basedAuthorization: Bearer <token> header
Session basedCookie like sessionid=abc123
API keysX-API-Key: my-secret-key header
OAuth 2.0"Login with Google" button
CertificatesClient TLS certificates between servers
One time codes (MFA)6 digit code from an authenticator app or SMS

All of these methods serve a single purpose: let the backend trust that "this request belongs to user X or client Y".

Important rule:
Authentication answers "Who is the caller?" and nothing else.
It does not decide what the caller is allowed to do.

Conceptually, authentication usually has these steps:

  1. Client sends credentials
    For example: username and password in a form, or a JWT in an HTTP header.
  2. Server verifies credentials
    • Compare password hash with stored hash
    • Validate signature of a JWT
    • Look up and check an API key
    • Validate a session ID in a session store
  3. Server attaches identity to the request
    In code, you often end up with something like:
python
   request.user = User(id=123, email="alice@example.com", role="admin")
  1. Request continues through the system
    Other parts of the backend (authorization checks, business logic) can now use request.user to decide what is allowed.

If authentication fails, your backend must treat the request as unauthenticated, and usually respond with status code 401 Unauthorized (yes, the name is confusing; it actually means "not authenticated").

What Is Authorization?

Authorization is about access control.

Once you know who is calling, you must decide what they are allowed to do. That decision is authorization.

Typical authorization questions:

Examples:

ScenarioAuthorization decision
Regular user tries to access /admin/usersDeny, only admins allowed
User tries to delete another user’s commentDeny, only comment owner or admin can delete
API client tries to read private dataAllow/deny based on its scopes or permissions
Employee tries to update salary tableAllow only HR role

Authorization usually uses:

Important rule:
Authorization answers "Is this authenticated caller allowed to do this exact thing?"
It depends on authenticated identity but is a separate step.

Common authorization patterns:

PatternDescription
Role based (RBAC)Decide access by user role, for example only admins can access endpoint
Permission based (PBAC)Fine grained permissions attached to users or roles
Attribute based (ABAC)Use attributes, for example department, region, subscription tier
Ownership checksUser can access only resources that belong to them

In HTTP APIs, when authorization fails, you typically use:

How Authentication and Authorization Work Together

You almost always perform authentication before authorization.

A simplified flow for a protected API endpoint:

  1. Request comes in
http
   GET /users/123/profile
   Authorization: Bearer eyJhbGciOi...
  1. Authentication middleware
    • Extract token from header
    • Validate signature and expiration
    • Decode token and find user in database
    • Attach user to request: request.user = User(id=123, role="user")
  2. Authorization in the route handler or service
    • Check if request.user has access to this profile
    • For example, allow if:
      • request.user.id == 123 same user
        or
      • request.user.role == "admin" admin
  3. Response
    • If authentication failed: return 401
    • If authentication succeeded but authorization failed: return 403
    • If both succeeded: return 200 with the requested data

Here is a very simple Python style pseudocode:

python
def get_user_profile(request, user_id):
    # Authentication is usually done by middleware before this
    if not request.user:  # user is None or anonymous
        return Response(status_code=401)
    # Authorization: can this user see this profile?
    if request.user.id != user_id and request.user.role != "admin":
        return Response(status_code=403)
    profile = load_profile_from_db(user_id)
    return Response(status_code=200, body=profile)

Notice how:

Concrete Examples You Already Know

To make the difference more intuitive, consider some everyday examples.

Example 1: Logging in to a Website

  1. You open /login and submit your email and password.
  2. Server checks if the password is correct.
    • This is authentication.
    • If incorrect, you stay unauthenticated.
  3. After login, you go to /admin.
    • The server checks if your user has role "admin".
    • This is authorization.

If your password is correct but you are not an admin:

Example 2: Viewing Your Bank Account

  1. You log in with username, password, maybe a one time code.
    • Bank verifies your identity authentication.
  2. You request /accounts/987654.
    • Server checks if account 987654 belongs to you.
    • If it belongs to another customer, you are not authorized to see it.

The bank needs both good authentication and good authorization:

Example 3: Public vs Private Endpoints

Some endpoints do not require authentication at all. For example:

Others do:

Flow:

In code, you often declare this explicitly, for example in a framework:

python
@app.get("/products")  # public
def list_products():
    ...
@app.get("/orders", dependencies=[Depends(auth_required)])  # authentication needed
def list_orders(current_user = Depends(get_current_user)):
    ...

Inside list_orders, you then apply further authorization checks.

Typical Mistakes Beginners Make

Understanding the difference is important because confusing them leads to security problems and messy code.

Mistake 1: "Logged in" Means "Can Do Anything"

Some beginners think that once a user is authenticated, they can access everything. For example:

python
def delete_user(user_id, request):
    if not request.user:
        # Only check if user is logged in
        return 401
    # Dangerous: allowing any logged in user to delete any account
    delete_user_from_db(user_id)
    return 200

This code is missing authorization.

Correct version should check who is doing this:

python
def delete_user(user_id, request):
    if not request.user:
        return 401  # not authenticated
    # Only allow admins or the user themself
    if request.user.id != user_id and request.user.role != "admin":
        return 403  # not authorized
    delete_user_from_db(user_id)
    return 200

Mistake 2: Mixing Authentication Logic with Authorization Logic Everywhere

Another common mistake is to spread both authentication and authorization logic across the whole codebase, with copy pasted checks in every endpoint.

Better approach:

This separation makes code clearer and easier to test.

Mistake 3: Wrong HTTP Status Codes

Backend beginners often return 401 or 403 randomly.

Use them like this:

SituationStatus code
User not authenticated, or missing token401 Unauthorized
User authenticated but not allowed403 Forbidden

This distinction helps API clients understand what went wrong:

How This Fits with the Rest of the Course

Later chapters in the Authentication section will go deeper into:

Those topics are all about authentication mechanisms.

The separate Authorization section will later cover:

Those topics are all about authorization strategies.

Summary

To keep in mind:

  • Authentication = verifying identity: "Who are you?"
  • Authorization = verifying access: "What are you allowed to do?"
  • Authentication happens first, authorization depends on its result.
  • Return 401 when authentication fails, 403 when authorization fails.

When you design backend endpoints, always think in two steps:

  1. How will this endpoint know who is calling it?
    This is your authentication plan.
  2. Once it knows, how will it decide if this caller can perform this action on this resource?
    This is your authorization plan.

Keeping these two concerns clearly separate will make your backends safer, easier to understand, and easier to extend.

Views: 6

Comments

Please login to add a comment.

Don't have an account? Register now!