Skip to main content

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.

Setup#

Authentication and User Data Fetching (login.ts)#

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");    }  },};

GraphQL Client (gql.ts)#

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;

React Login Component(login.tsx)#

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;
Quiz dataset