Learn
09.4 | AUTHENTICATION, SESSIONS AND ACCESS RULES
01 | TWO QUESTIONS THAT SOUND SIMILAR
Authentication asks whether the presented identity has been established, such as by checking a passphrase. Authorisation asks whether that identity may perform this operation on this particular record. A successful sign-in does not answer every later permission question.
A student may edit their own project but not another student’s project. A teacher may read shared projects and write feedback, but not rewrite students’ summaries or open their private drafts under this portal’s policy.
Hiding a button makes the interface clearer, but a person can request the URL directly. The server must enforce the same rule for the actual request, regardless of what the page displayed.
02 | EXAMINE THE PORTAL AS A COMPLETE EXAMPLE
The portal download is the capstone for this section. Its complete source shows authentication and access checks in context, rather than offering a few disconnected security lines that look complete.
Accounts are created through a trusted local CLI command with a prompted passphrase and selected student or teacher role. There is no public registration or a form allowing a student to appoint themselves a teacher.
For local classroom practice, use invented account names and passphrases. A public service with real accounts additionally needs abuse controls, identity-management processes, recovery, monitoring and an operational review; this teaching project does not claim to provide those.
Download the student project portal03 | HASH PASSPHRASES, DO NOT STORE THEM AS TEXT
A password hash is a one-way verification representation. Werkzeug’s helpers create and check a salted, deliberately costly scrypt hash in this project. On sign-in, check_password_hash verifies the submitted passphrase against the stored representation.
A salt helps prevent identical passphrases having identical stored hashes. A costly algorithm increases the work of guessing after a database leak. This is different from encrypting a password so the app can recover and display it.
The CLI requires a passphrase of twelve to 128 characters and reads it without echoing it. This is the teaching project’s policy, not a complete strength assessment or breached-password check. Do not print, email or log submitted passwords.
from werkzeug.security import generate_password_hash, check_password_hash
# Fictional test value, not a real account password.
stored = generate_password_hash("Fictional practice phrase 42", method="scrypt")
print("Correct:", check_password_hash(stored, "Fictional practice phrase 42"))
print("Wrong:", check_password_hash(stored, "wrong"))EXPECTED OUTPUT
Correct: True Wrong: False
04 | WHAT A SIGNED SESSION COOKIE MEANS
HTTP requests do not inherently remember a previous sign-in. Flask’s default session mechanism stores session values in a client-side cookie protected by a signature. The signature helps detect changes when the signing secret remains private.
Signed is not encrypted. Do not store passwords, secret API keys or sensitive student records in that cookie. The portal stores a user ID, a form token and session metadata, then loads the current user record from the database each request.
The cookie is a bearer credential: someone possessing a still-valid authenticated cookie may use it. Clearing it on logout signs out that browser, but does not revoke every previously copied signed cookie. Broader revocation needs a deliberate server-side session or token-version design.
05 | SECRET AND COOKIE SETTINGS HAVE DIFFERENT JOBS
PORTAL_SECRET must be a strong random signing value loaded from the environment; there is no committed default secret. Changing it invalidates existing signatures, so choose and rotate it deliberately. Every worker must use the intended same secret.
HttpOnly limits ordinary JavaScript access to the cookie. Secure limits cookie transmission to HTTPS. SameSite=Lax reduces some cross-site cookie sending, but does not replace explicit form protection or access checks.
The portal enables Secure cookies in production mode and leaves that flag off for the local loopback HTTP lab. With Secure enabled on plain HTTP, the browser will not normally send the cookie, which can make sign-in appear to fail. Use an HTTPS deployment, not a weakened production flag.
06 | VERIFY THE USER AND THEN THE RECORD
On each request, the portal reads the session’s user ID and loads an active user from the database. Role comes from that current record, not from a posted role field or a cached privileged value a client supplies.
Reading a project checks whether the requester is its owner or a teacher viewing a shared record. Editing and deleting require the student owner. Feedback requires a teacher and a shared record.
The create route sets owner_id from g.user["id"], ignoring a forged posted owner_id. Update and delete statements also include the ownership condition. An integer route converter helps parse an ID; it does not prove permission.
| Requester | Own draft | Another student’s shared project | Edit student summary |
|---|---|---|---|
| Student owner | Read and edit own record | Denied | Only own record |
| Other student | Denied | Denied | Denied |
| Teacher | Private draft denied | Read and give feedback if shared | Denied |
| Anonymous | Sign-in required | Sign-in required | Sign-in required |
07 | UNDERSTAND CROSS-SITE REQUEST FORGERY
A browser may attach a site’s cookies when sending a request. A hostile page can try to make an already signed-in browser submit an unwanted action without proving it used your intended form. This is cross-site request forgery, or CSRF.
The portal includes a random session-linked token in every state-changing form, including sign-in and sign-out. The server compares it before accepting the request. It replaces session state and the token after successful authentication.
CSRF protection does not grant record permission or solve cross-site scripting. Token comparison, ownership checks, HTML escaping and cookie settings protect different parts of the flow. A hidden field called owner_id is not a reliable identity source.
08 | APPLY A ROLE AND OWNERSHIP RULE
This fixed model evaluates one policy decision. It does not sign anyone in or grant privileges; the actual portal reloads identity from its database and enforces the rule on the server.
09 | CHECK FAILURE WITHOUT LEAKING EXTRA INFORMATION
The portal uses the same visible sign-in failure message for an unknown username and wrong passphrase. A dummy hash check makes an unknown account take a comparable verification path, but is not a proof that every timing side channel is eliminated.
Limit input size and plan rate limiting before public account use. Password hashing does not stop online guessing, automated abuse or excessive resource consumption. Those need operational controls too.
Test forged direct requests, not only buttons. A student request to another ID should be denied, a missing form token should fail and disabling a user should remove access on the next request.
10 | KNOW WHEN TO USE AN IDENTITY PROVIDER
An established identity provider can handle flows such as Google sign-in through a supported OAuth/OpenID Connect integration. That introduces provider configuration, redirect handling and identity-validation rules; it is not just a button that skips security work.
This portal teaches local password and session concepts. It is separate from Computer Science Café’s future real-user account system and does not claim to implement Google sign-in, subscription entitlements or privacy-policy compliance.
Try it: read the permission matrix, write a test for a denied action and verify the protected record remains unchanged. Use therefore or because to explain why a login alone is insufficient.
PUT YOUR SKILLS TO WORK
Use the Section 9 challenges to practise these ideas independently. Work in your Python editor, predict results and keep a short test record.
Section 9 challenges Python course navigation