Skip to content

Commit f80d22d

Browse files
committed
init commit
0 parents  commit f80d22d

File tree

12 files changed

+595
-0
lines changed

12 files changed

+595
-0
lines changed

.gitignore

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Binaries for programs and plugins
2+
*.exe
3+
*.exe~
4+
*.dll
5+
*.so
6+
*.dylib
7+
8+
# Test binary, build with `go test -c`
9+
*.test
10+
11+
# Output of the go coverage tool, specifically when used with LiteIDE
12+
*.out

LICENSE.txt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2019 Max
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Golang AWS Cognito Register, Verify phone number, Login and Get User example
2+
3+
This example code demonstrates how to use AWS Cognito with AWS Go SDK in a form of simple web pages where you can:
4+
5+
1. Check if username is taken
6+
2. Register
7+
3. Verify user's phone
8+
4. Login with username or refresh token
9+
10+
In order this solution to work, you need to have AWS credentials configured (file `.aws/configuration` exists) and User Pool created in AWS Console. You have to disable "Remember device" and enable "Sms second-factor" on authentication tab.
11+
12+
You will also need to create App Client in User Pool without "Generate Secret Key" checkbox. When the app client is created, in it's settings select "Enable username-password (non-SRP) flow for app-based authentication (USER_PASSWORD_AUTH)".
13+
14+
## Build
15+
16+
Go to `/src` folder and run:
17+
18+
```go
19+
go build -o ./build/cognito
20+
21+
AWS_PROFILE=XXX COGNITO_APP_CLIENT_ID=XXX COGNITO_USER_POOL_ID=XXX ./build/cognito
22+
```
23+
24+
Visit http://localhost:8080/register to see the registration page.

public/login.html

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
7+
<link
8+
rel="stylesheet"
9+
href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/semantic.min.css"
10+
/>
11+
<title>Login</title>
12+
<style>
13+
.holder {
14+
display: flex;
15+
align-items: center;
16+
justify-content: center;
17+
}
18+
code {
19+
font-size: 9px !important;
20+
overflow-x: scroll;
21+
}
22+
</style>
23+
</head>
24+
<body class="holder">
25+
<div class="ui raised text container">
26+
<div class="column">
27+
<h1 class="ui header">Login</h1>
28+
<div class="ui compact message hidden" id="message">
29+
<p>
30+
Message goes here...
31+
</p>
32+
</div>
33+
34+
<div class="ui styled fluid accordion">
35+
<div class="active title">
36+
<i class="dropdown icon"></i>
37+
Username / Password
38+
</div>
39+
<div class="active content">
40+
<form class="ui form padded" method="post" action="/login">
41+
<div class="field">
42+
<label>Username</label>
43+
<input
44+
type="text"
45+
name="username"
46+
required
47+
placeholder="Please enter your username or refresh token"
48+
/>
49+
</div>
50+
<div class="field">
51+
<label>Password</label>
52+
<input
53+
type="password"
54+
name="password"
55+
required
56+
placeholder="Wh4t_i5_your_p@ssw0rd?"
57+
/>
58+
</div>
59+
<button class="ui button" type="submit">Submit</button>
60+
</form>
61+
</div>
62+
<div class="title">
63+
<i class="dropdown icon"></i>
64+
Refresh token
65+
</div>
66+
<div class="content">
67+
<form class="ui form padded" method="post" action="/login">
68+
<div class="field">
69+
<input type="hidden" name="refresh" value="1" />
70+
71+
<label>Refresh token</label>
72+
<input
73+
type="text"
74+
name="refresh_token"
75+
required
76+
placeholder="Please enter the refresh token"
77+
/>
78+
</div>
79+
<button class="ui button" type="submit">Submit</button>
80+
</form>
81+
</div>
82+
</div>
83+
84+
<code class="ui compact message hidden" id="authres">
85+
Message goes here...
86+
</code>
87+
</div>
88+
</div>
89+
</body>
90+
<script
91+
src="https://code.jquery.com/jquery-3.1.1.min.js"
92+
integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8="
93+
crossorigin="anonymous"
94+
></script>
95+
<script src="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/semantic.min.js"></script>
96+
<script>
97+
$(".ui.accordion").accordion();
98+
99+
if (document.location.search.includes("error")) {
100+
const m = document.getElementById("message");
101+
m.style.display = "block";
102+
const err = document.location.search.replace("?error=", "");
103+
m.textContent = decodeURI(err);
104+
}
105+
if (document.location.search.includes("authres")) {
106+
const m = document.getElementById("authres");
107+
m.style.display = "block";
108+
const err = document.location.search.replace("?authres=", "");
109+
m.textContent = decodeURI(err);
110+
}
111+
</script>
112+
</html>

public/otp.html

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
7+
<link
8+
rel="stylesheet"
9+
href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/semantic.min.css"
10+
/>
11+
<title>OTP</title>
12+
<style>
13+
.holder {
14+
display: flex;
15+
align-items: center;
16+
justify-content: center;
17+
}
18+
</style>
19+
</head>
20+
<body class="holder">
21+
<div class="ui raised text container">
22+
<div class="column">
23+
<h1 class="ui header">Verify phone number</h1>
24+
<div class="ui compact message hidden" id="message">
25+
<p>
26+
Message goes here...
27+
</p>
28+
</div>
29+
<form class="ui form padded segment" method="post" action="/otp">
30+
<div class="field">
31+
<label>One time code</label>
32+
<input type="text" name="otp" required placeholder="XXXXXX" />
33+
</div>
34+
<button class="ui button" type="submit">Submit</button>
35+
</form>
36+
</div>
37+
</div>
38+
</body>
39+
<script>
40+
if (document.location.search.includes("error")) {
41+
const m = document.getElementById("message");
42+
m.style.display = "block";
43+
const err = document.location.search.replace("?error=", "");
44+
m.textContent = decodeURI(err);
45+
}
46+
</script>
47+
</html>

public/register.html

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
7+
<link
8+
rel="stylesheet"
9+
href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/semantic.min.css"
10+
/>
11+
<title>Register</title>
12+
<style>
13+
.holder {
14+
display: flex;
15+
align-items: center;
16+
justify-content: center;
17+
}
18+
#message {
19+
display: none
20+
}
21+
</style>
22+
</head>
23+
<body class="holder">
24+
<div class="ui raised text container">
25+
<div class="column">
26+
<h1 class="ui header">Register</h1>
27+
<div class="ui compact message" id="message">
28+
<p>
29+
An error ocurred during your request.
30+
</p>
31+
</div>
32+
<form class="ui form padded segment" method="post" action="/register">
33+
<div class="field">
34+
<label>Username</label>
35+
<input
36+
type="text"
37+
name="username"
38+
required
39+
placeholder="User name"
40+
/>
41+
</div>
42+
<div class="field">
43+
<label>Password</label>
44+
<input
45+
type="password"
46+
name="password"
47+
required
48+
placeholder="Password"
49+
/>
50+
</div>
51+
<div class="field">
52+
<label>Phone number</label>
53+
<input
54+
type="text"
55+
name="phone_number"
56+
required
57+
placeholder="+XXXXXXXXXXX"
58+
/>
59+
</div>
60+
<button class="ui button" type="submit">Submit</button>
61+
</form>
62+
</div>
63+
</div>
64+
</body>
65+
<script>
66+
if (document.location.search.includes("error")) {
67+
const m = document.getElementById("message")
68+
m.style.display = "block"
69+
const err = document.location.search.replace("?error=", "")
70+
m.textContent = decodeURI(err);
71+
}
72+
</script>
73+
</html>

public/username.html

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
7+
<link
8+
rel="stylesheet"
9+
href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/semantic.min.css"
10+
/>
11+
<title>Check username</title>
12+
<style>
13+
.holder {
14+
display: flex;
15+
align-items: center;
16+
justify-content: center;
17+
}
18+
</style>
19+
</head>
20+
<body class="holder">
21+
<div class="ui raised text container">
22+
<div class="column">
23+
<h1 class="ui header">Check username</h1>
24+
<div class="ui compact message hidden" id="message">
25+
<p>
26+
Message goes here...
27+
</p>
28+
</div>
29+
<form class="ui form padded segment" method="post" action="/username">
30+
<div class="field">
31+
<label>Check if username is taken</label>
32+
<input type="text" name="username" required placeholder="Please enter the username" />
33+
</div>
34+
<button class="ui button" type="submit">Submit</button>
35+
</form>
36+
</div>
37+
</div>
38+
</body>
39+
<script>
40+
if (document.location.search.includes("error")) {
41+
const m = document.getElementById("message");
42+
m.style.display = "block";
43+
const err = document.location.search.replace("?error=", "");
44+
m.textContent = decodeURI(err);
45+
}
46+
</script>
47+
</html>

src/login.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"net/http"
6+
7+
"github.com/aws/aws-sdk-go/aws"
8+
9+
cognito "github.com/aws/aws-sdk-go/service/cognitoidentityprovider"
10+
)
11+
12+
const flowUsernamePassword = "USER_PASSWORD_AUTH"
13+
const flowRefreshToken = "REFRESH_TOKEN_AUTH"
14+
15+
// Login handles login scenario.
16+
func (c *CognitoExample) Login(w http.ResponseWriter, r *http.Request) {
17+
r.ParseForm()
18+
19+
username := r.Form.Get("username")
20+
password := r.Form.Get("password")
21+
refresh := r.Form.Get("refresh")
22+
refreshToken := r.Form.Get("refresh_token")
23+
24+
flow := aws.String(flowUsernamePassword)
25+
params := map[string]*string{
26+
"USERNAME": aws.String(username),
27+
"PASSWORD": aws.String(password),
28+
}
29+
30+
if refresh != "" {
31+
flow = aws.String(flowRefreshToken)
32+
params = map[string]*string{
33+
"REFRESH_TOKEN": aws.String(refreshToken),
34+
}
35+
}
36+
37+
authTry := &cognito.InitiateAuthInput{
38+
AuthFlow: flow,
39+
AuthParameters: params,
40+
ClientId: aws.String(c.AppClientID),
41+
}
42+
43+
res, err := c.CognitoClient.InitiateAuth(authTry)
44+
if err != nil {
45+
fmt.Println(err)
46+
http.Redirect(w, r, fmt.Sprintf("/login?error=%s", err.Error()), http.StatusSeeOther)
47+
return
48+
}
49+
50+
http.Redirect(w, r, fmt.Sprintf("/login?authres=%s", res.AuthenticationResult), http.StatusFound)
51+
}

0 commit comments

Comments
 (0)