Authentication & Authorization
To communicate with EYWA backend, especially with graphql endpoint, first you have to authenticate and afterwards authorize your application, webpage or something else.
#
Setuplogin.ts
)#
Authentication and User Data Fetching (To communicate with EYWA backend, especially with graphql endpoint, first you have to authenticate and afterwards authorize your application, webpage or something else.
.Login
/eywa/login
endpoint will accepts POST requests that will look at body payload to get name, password
and account parameters. Based on these parameters EYWA will return token in HTTP body that
app can than reuse to communicate with other EYWA services.
.Who am I? Probably you will wan't your application to be totally transparent without preconditions or any logic to handle user specifics. To that end EYWA provides reflection end point that will tell your application witch user is currently working on it.
By sending HTTP GET to /eywa/whoami
endpoint EYWA will return information that are stored
in EYWA Token. Not all of them obviously.
npm i axios
import axios from "axios";
export const HttpClient = axios.create({ baseURL: `http://localhost:8080/eywa`, // This should be moved to .env});
export function setAuthToken(token = "") { HttpClient.defaults.headers.common.Authorization = `Bearer ${token}`;}
export const Api = { async whoami(token?: string | null | undefined) { try { const options = token ? { headers: { Authorization: `Bearer ${token}` } } : {}; const { data } = await HttpClient.get("/whoami", options); // /whoami route returns the user's data return data; } catch (err) { throw new Error("http.ts: Whoami failed"); } },
async login(username: string, password: string) { try { const { data } = await HttpClient.post("/login", { username, password, }); return data; } catch (err) { console.log(err); throw new Error("http.ts: Login failed"); } },};
gql.ts
)#
GraphQL Client (This file sets up the GraphQL client to communicate with the EYWA graphql endpoint.
First you need to install graphql-request:
npm i graphql-request
import { GraphQLClient } from "graphql-request";
const GRAPHQL_ENDPOINT = "http://localhost:8080/graphql"; // This should be moved to .env
export const client = new GraphQLClient(`${GRAPHQL_ENDPOINT}`, { headers: { authorization: `Bearer ${localStorage.getItem("token")}`, },});
export function setAuthToken(token: string | null | undefined) { client.setHeader("authorization", `Bearer ${token}`);}
export default client;
login.tsx
)#
React Login Component(Here is an example of a React login component that integrates with the EYWA platform:
import { useState } from "react";import { useNavigate } from "react-router-dom";import { Button, Form, FormGroup, Label, Input } from "reactstrap";import Layout from "@/components/ui/Layout";import { Api, setAuthToken } from "@/utils/login";import { useUserDispatch } from "@/context/userContext";import { setAuthToken as setGqlAuthToken } from "@/utils/gql";
function Login() { const [username, setUsername] = useState(""); const [password, setPassword] = useState(""); const dispatch = useUserDispatch(); const navigate = useNavigate();
const handleUsernameChange = (e) => { setUsername(e.target.value); };
const handlePasswordChange = (e) => { setPassword(e.target.value); };
const handleSuccessfullLogin = async (authToken) => { // Set the auth token in the axios instance setAuthToken(authToken); // Set the auth token in the gql client setGqlAuthToken(authToken); // Fetch the user data const userData = await Api.whoami(authToken); // Set the token in the local storage localStorage.setItem("token", authToken); // Set the token and user data in the context dispatch({ type: "login", value: { token: authToken, userData } }); // Navigate to the home page navigate(`${import.meta.env.BASE_URL}home/`); };
const handleFailedLogin = () => { // Your logic for failed login };
const handleLogin = async (e) => { e.preventDefault(); const authToken = await Api.login(username, password); authToken ? handleSuccessfullLogin(authToken) : handleFailedLogin(); };
return ( <Layout> <div> <h2>Login</h2> <Form onSubmit={handleLogin}> <FormGroup> <Label for="username">Username:</Label> <Input type="text" id="username" value={username} onChange={handleUsernameChange} /> </FormGroup> <FormGroup> <Label for="password">Password:</Label> <Input type="password" id="password" value={password} onChange={handlePasswordChange} /> </FormGroup> <Button type="submit">Login</Button> </Form> </div> </Layout> );}
export default Login;