Anonymous Access
This example builds on top of the Login Page example. This time instead of having a user navigate to the home page, and then be immediately redirected to the login page, this time we'll allow an unauthenticated user to access the home page.
When this unauthenticated user accesses the home page, they'll be a switch in logic to show different content and a login button - rather than a greeting and a logout button.
Allow Anon
The first thing we need to do is specify that the home page route should allow anonymous access. To achieve this we can use the -AllowAnon
switch on Add-PodeRoute
. With this switch, if the user isn't authenticated - even if the -Authentication
parameter supplied - then the home page will still load anyway.
Below is the home page route from the Login Page example, but now with anonymous access allowed:
Add-PodeRoute -Method Get -Path '/' -Authentication 'Login' -AllowAnon -ScriptBlock {
$WebEvent.Session.Data.Views++
Write-PodeViewResponse -Path 'auth-home' -Data @{
Username = $WebEvent.Auth.User.Name;
Views = $WebEvent.Session.Data.Views;
}
}
Now when a user navigates to http://localhost:8080/
they won't be redirected to http://localhost:8080/login
.
Is there a User?
However, now we have an issue: if an authenticated or an unauthenticated user access the home page, they'll both be greeted with the same content! This is hardly desirable, so we need a way to test if whether we have an authenticated user or not.
To achieve this we can use Test-PodeAuthUser
. This function will return whether or not the current request (or $WebEvent
) has an authenticated user, if it does then we can show the original content and if not we can show different content:
Add-PodeRoute -Method Get -Path '/' -Authentication 'Login' -AllowAnon -ScriptBlock {
if (Test-PodeAuthUser) {
$session:Views++
Write-PodeViewResponse -Path 'auth-home' -Data @{
Username = $WebEvent.Auth.User.Name
Views = $session:Views
}
}
else {
Write-PodeViewResponse -Path 'auth-home-anon'
}
}
Now, when an authenticated user hits the page, they're shown the original personal greeting page with view counter. However, when an unauthenticated user hits the page they are shown a generic greeting with a login button.
The Test-PodeAuthUser
will check both the $WebEvent.Auth
and $WebEvent.Session
objects for an authenticated user. You can force the function to only check the former by supplying -IgnoreSession
.
You can also retrieve the user object using Get-PodeAuthUser
. Under most circumstances you'll be able to access the authenticated user at $WebEvent.Auth.User
, however if you're relying on Sessions and a Route without Authentication configured then you'll ave to use this function. Similar to above, you can supply -IgnoreSession
here as well.
Example Code
This is the full code for the server above:
Start-PodeServer -Thread 2 {
Add-PodeEndpoint -Address * -Port 8080 -Protocol Http
# use pode template engine
Set-PodeViewEngine -Type Pode
# setup session middleware
Enable-PodeSessionMiddleware -Duration 120 -Extend
# setup form authentication
New-PodeAuthScheme -Form | Add-PodeAuth -Name 'Login' -FailureUrl '/login' -SuccessUrl '/' -ScriptBlock {
param($username, $password)
# here you'd check a real user storage, this is just for example
if ($username -eq 'morty' -and $password -eq 'pickle') {
return @{
User = @{
ID ='M0R7Y302'
Name = 'Morty'
Type = 'Human'
}
}
}
# aww geez! no user was found
return @{ Message = 'Invalid details supplied' }
}
# the "GET /" endpoint for the homepage
Add-PodeRoute -Method Get -Path '/' -Authentication 'Login' -AllowAnon -ScriptBlock {
if (Test-PodeAuthUser) {
$session:Views++
Write-PodeViewResponse -Path 'auth-home' -Data @{
Username = $WebEvent.Auth.User.Name
Views = $session:Views
}
}
else {
Write-PodeViewResponse -Path 'auth-home-anon'
}
}
# the "GET /login" endpoint for the login page
Add-PodeRoute -Method Get -Path '/login' -Authentication 'Login' -Login -ScriptBlock {
Write-PodeViewResponse -Path 'auth-login' -FlashMessages
}
# the "POST /login" endpoint for user authentication
Add-PodeRoute -Method Post -Path '/login' -Authentication 'Login' -Login
# the "POST /logout" endpoint for ending the session
Add-PodeRoute -Method Post -Path '/logout' -Authentication 'Login' -Logout
}
Pages
The following are the web pages used above, as well as the CSS style. The web pages have been created using .pode
files, which allows you to embed PowerShell into the files.
auth-home.pode
<html>
<head>
<title>Auth Home</title>
<link rel="stylesheet" type="text/css" href="/styles/main.css">
</head>
<body>
Hello, $($data.Username)! You have view this page $($data.Views) times!
<form action="/logout" method="post">
<div>
<input type="submit" value="Logout"/>
</div>
</form>
</body>
</html>
auth-home-anon.pode
<html>
<head>
<title>Auth Home</title>
<link rel="stylesheet" type="text/css" href="/styles/simple.css">
</head>
<body>
Hello, there! Welcome to the home page, please login below.
<form action="/login" method="get">
<div>
<input type="submit" value="Login"/>
</div>
</form>
</body>
</html>
auth-login.pode
<html>
<head>
<title>Auth Login</title>
<link rel="stylesheet" type="text/css" href="/styles/main.css">
</head>
<body>
Please Login:
<form action="/login" method="post">
<div>
<label>Username:</label>
<input type="text" name="username"/>
</div>
<div>
<label>Password:</label>
<input type="password" name="password"/>
</div>
<div>
<input type="submit" value="Login"/>
</div>
</form>
</body>
</html>
styles/main.css
body {
background-color: rebeccapurple;
}