Serverless Auth Strategies with Netlify Identity Divya Sasidharan @shortdiv

Why Authentication?

What is Authentication?

Login ??? Log Out Logged In

SSO MFA Silent Auth Social Login Passwordless

https://www.netlify.com/blog/ 2018/11/28/authentication-for-therest-of-us/

Netlify Identity

<script type=”text/javascript” src=”https://identity.netlify.com/v1/ netlify-identity-widget.js”></script>

yarn add netlify-identity-widget

const netlifyIdentity = require(‘netlify-identity-widget’); netlifyIdentity.open(); const user = netlifyIdentity.currentUser(); netlifyIdentity.on(‘init’, user => { console.log(‘init’, user) }); netlifyIdentity.on(‘login’, user => { console.log(‘login’, user) }); netlifyIdentity.on(‘logout’, user => { console.log(‘logout’) }); netlifyIdentity.close();

const netlifyIdentity = require(‘netlify-identity-widget’); netlifyIdentity.open(); const user = netlifyIdentity.currentUser(); netlifyIdentity.on(‘init’, user => { console.log(‘init’, user) }); netlifyIdentity.on(‘login’, user => { console.log(‘login’, user) }); netlifyIdentity.on(‘logout’, user => { console.log(‘logout’) }); netlifyIdentity.close();

const netlifyIdentity = require(‘netlify-identity-widget’); netlifyIdentity.open(); const user = netlifyIdentity.currentUser(); netlifyIdentity.on(‘init’, user => { console.log(‘init’, user) }); netlifyIdentity.on(‘login’, user => { console.log(‘login’, user) }); netlifyIdentity.on(‘logout’, user => { console.log(‘logout’) }); netlifyIdentity.close();

const netlifyIdentity = require(‘netlify-identity-widget’); netlifyIdentity.open(); const user = netlifyIdentity.currentUser(); netlifyIdentity.on(‘init’, user => { console.log(‘init’, user) }); netlifyIdentity.on(‘login’, user => { console.log(‘login’, user) }); netlifyIdentity.on(‘logout’, user => { console.log(‘logout’) }); netlifyIdentity.close();

const netlifyIdentity = require(‘netlify-identity-widget’); netlifyIdentity.open(); const user = netlifyIdentity.currentUser(); netlifyIdentity.on(‘init’, user => { console.log(‘init’, user) }); netlifyIdentity.on(‘login’, user => { console.log(‘login’, user) }); netlifyIdentity.on(‘logout’, user => { console.log(‘logout’) }); netlifyIdentity.close();

Demo Time!

MUCH FUN SUCH FUNCTIONS

export function handler(event, context, callback) { console.log(event) callback(null, { statusCode: 200, body: JSON.stringify({msg: “Hello, World!”}) }) } src/lambda/hello.js

[build] command = “yarn build” functions = “lambda” publish = “dist” netlify.toml

/.netlify/functions/{function_name}

/.netlify/functions/login

Custom Webhooks API Call

Custom Webhooks API Call

netlifyIdentity.on(‘signup’, user => { axios({ url: /.identity/functions/login, method: “GET” }) });

netlifyIdentity.on(‘signup’, user => { axios({ url: /.identity/functions/login, method: “GET” }) });

Custom Webhooks API Call Automagic web hooks

validate signup login

export function handler(event, context, callback) { console.log(event) callback(null, { statusCode: 200, body: JSON.stringify({msg: “Hello, World!”}) }) } src/lambda/identity-login.js

exports.handler = function(event, context, callback) { const {identity, user} = context.clientContext; // do some stuff // callback(null, { statusCode: 200, body: JSON.stringify({ msg: “hello”}) }); };

exports.handler = function(event, context, callback) { const {identity, user} = context.clientContext; // do some stuff // callback(null, { statusCode: 200, body: JSON.stringify({ msg: “hello”}) }); };

exports.handler = function(event, context, callback) { const {identity, user} = context.clientContext; // do some stuff // callback(null, { statusCode: 200, body: JSON.stringify({ msg: “hello”}) }); };

exports.handler = function(event, context, callback) { const data = JSON.parse(event.body); const { user } = data; console.log(user.email); console.log(“identity yourself”, context.clientContext.identity); const validateUser = email => { if (email.split(“@”)[1] === “netlify.com”) { return [“editor”]; } else { return [“visitor”]; } }; const roles = validateUser(user.email); const responseBody = { app_metadata: { roles, my_user_info: “this is user info that the user can’t change from the UI” }, user_metadata: { …user.user_metadata, custom_data_from_function: “hurray this is some extra metadata” } }; }; callback(null, { statusCode: 200, body: JSON.stringify(responseBody) });

exports.handler = function(event, context, callback) { const data = JSON.parse(event.body); const { user } = data; console.log(user.email); console.log(“identity yourself”, context.clientContext.identity); const validateUser = email => { if (email.split(“@”)[1] === “netlify.com”) { return [“editor”]; } else { return [“visitor”]; } }; const roles = validateUser(user.email); const responseBody = { app_metadata: { roles, my_user_info: “this is user info that the user can’t change from the UI” }, user_metadata: { …user.user_metadata, custom_data_from_function: “hurray this is some extra metadata” } }; }; callback(null, { statusCode: 200, body: JSON.stringify(responseBody) });

exports.handler = function(event, context, callback) { const data = JSON.parse(event.body); const { user } = data; console.log(user.email); console.log(“identity yourself”, context.clientContext.identity); const validateUser = email => { if (email.split(“@”)[1] === “netlify.com”) { return [“editor”]; } else { return [“visitor”]; } }; const roles = validateUser(user.email); const responseBody = { app_metadata: { roles, my_user_info: “this is user info that the user can’t change from the UI” }, user_metadata: { …user.user_metadata, custom_data_from_function: “hurray this is some extra metadata” } }; }; callback(null, { statusCode: 200, body: JSON.stringify(responseBody) });

exports.handler = function(event, context, callback) { const data = JSON.parse(event.body); const { user } = data; console.log(user.email); console.log(“identity yourself”, context.clientContext.identity); const validateUser = email => { if (email.split(“@”)[1] === “netlify.com”) { return [“editor”]; } else { return [“visitor”]; } }; const roles = validateUser(user.email); const responseBody = { app_metadata: { roles, my_user_info: “this is user info that the user can’t change from the UI” }, user_metadata: { …user.user_metadata, custom_data_from_function: “hurray this is some extra metadata” } }; }; callback(null, { statusCode: 200, body: JSON.stringify(responseBody) });

exports.handler = function(event, context, callback) { const data = JSON.parse(event.body); const { user } = data; console.log(user.email); console.log(“identity yourself”, context.clientContext.identity); const validateUser = email => { if (email.split(“@”)[1] === “netlify.com”) { return [“editor”]; } else { return [“visitor”]; } }; const roles = validateUser(user.email); const responseBody = { app_metadata: { roles, my_user_info: “this is user info that the user can’t change from the UI” }, user_metadata: { …user.user_metadata, custom_data_from_function: “hurray this is some extra metadata” } }; }; callback(null, { statusCode: 200, body: JSON.stringify(responseBody) });

{ }; app_metadata: { roles, …user.app_metadata, my_user_info: “some user info” }, user_metadata: { …user.user_metadata, custom_data_from_function: “hurray extra metadata!” }

{ }; app_metadata: { roles, …user.app_metadata, my_user_info: “some user info” }, user_metadata: { …user.user_metadata, custom_data_from_function: “hurray extra metadata!” }

Demo Time!

What about local development?

Netlify Identity

GoTrue An SWT based API for managing users and issuing SWT tokens GoTrueJS

import GoTrue from “gotrue-js”; export const auth = new GoTrue({ APIUrl: “https://auth-to-know.com/.netlify/identity”, audience: “”, setCookie: false });

const attemptLogin = ({ commit, dispatch }, creds) => { return new Promise((resolve, reject) => { auth .login(creds.email, creds.password) .then(response => { resolve(response); commit(“SET_CURRENT_USER”, response); }) .catch(error => { reject(error.json); }); }); };

https://www.netlify.com/blog/ 2018/12/07/gotrue-js—-bringingauthentication-to-static-sites-withjust-3kb-of-js/

! serverless chicago https://noti.st/shortdiv Divya Sasidharan @shortdiv