3️⃣Step 3 - Integrating Eartho into your server
Last updated
Last updated
If you use Eartho One with an app or site that communicates with a backend server, you can protect your routes easily with our SDK as well.
After your users finish logging in with Eartho, they'll be returned to your application at the callback
route.
Every request that your client makes to your server, send with the ID token on the client side
const idToken = await earthoOne.getIdToken();
const response = await fetch('https://api.example.com/products', {
headers: {
Authorization: `Bearer ${idToken}`
}
});
Check and verify the integrity of the ID token and use it to protect the API routes that you want to protect.
Step 1: Installing Required Packages
npm install @eartho/one-server-node
Step 2: Protecting Your Routes
Use the Eartho SDK to protect routes that require user authentication. For example, to protect a route that fetches user data, you would verify the user's ID token sent with the request.
const {EarthoOne} = require('@eartho/one-server-node');
const serverEarthoOneOptions = {
clientId: "client id",
clientSecret: "secret key"
}
const serverEarthoOne = new EarthoOne(serverEarthoOneOptions);
//Or check by yourself
getEarthoOne()
.getVerifiedUser(idToken)
.then((decodedToken) => {
const uid = decodedToken.uid;
const displayName = decodedToken.displayName;
const email = decodedToken.email;
const photoURL = decodedToken.photoURL;
// ...
})
.catch((error) => {
// Handle error
});
This guide assumes you have a basic understanding of Go and its package management system. Below is a step-by-step guide to help you set up Eartho in a Go server application for authenticating users and securing your API routes.
Before integrating Eartho into your Go server, ensure your Go environment is correctly set up. You should have Go installed on your system (visit the official Go website for instructions if you haven't).
bashCopy codego get github.com/dgrijalva/jwt-go
Create a new Go file for your server, for example, main.go
. Import the necessary packages:
goCopy codepackage main
import (
"fmt"
"net/http"
// Import the JWT package or Eartho SDK package here
"github.com/dgrijalva/jwt-go"
// Assuming `github.com/dgrijalva/jwt-go` is the JWT handler
)
Assuming your front end sends the ID token to your Go server in the Authorization
header, you'll want to extract and verify this token in your server routes:
goCopy codefunc verifyToken(w http.ResponseWriter, r *http.Request) {
// Extract the token from the Authorization header
authHeader := r.Header.Get("Authorization")
tokenString := // Extract the token from authHeader
// Verify the token
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
// Validate the alg is what you expect:
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
}
// Return the secret key or public key against which to verify the token
// For example, return []byte("your-verification-key"), nil
})
if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
// Token is valid, and you can extract claims
// For example, userID := claims["uid"].(string)
} else {
// Handle invalid token
}
}
Use the verifyToken
function as middleware or within specific routes to protect them. Ensure you're checking the token before allowing access to any sensitive information.
goCopy codehttp.HandleFunc("/protected", verifyToken)
Step 1: Install PyJWT
First, install PyJWT and a HTTP library like requests
, if you don't already have it. These libraries are necessary for verifying JWTs and optionally fetching public keys from Eartho's servers for signature verification.
pip install PyJWT requests cryptography
Step 2: Configure Your Web Server
Assuming you're using Flask, set up a basic server. If you're using another framework, the setup will be similar but may require different syntax.
from flask import Flask, request, jsonify
app = Flask(__name__)
Step 3: Define a Route to Verify Eartho Tokens
Create a protected route that requires a valid JWT for access. You'll extract the JWT from the Authorization header, verify it, and then proceed based on the verification result.
import jwt
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
import requests
from flask import Flask, jsonify
# Your Eartho project's JWT configuration
EARTHO_ISSUER = 'https://one.eartho.world/'
EARTHO_AUDIENCE = '<EARTHO_CLIENT_ID>' # Take it from the security tab in creator.eartho.io
EARTHO_PUBLIC_KEY = '<EARTHO_SECREY_KEY>' # Take it from the security tab in creator.eartho.io
app = Flask(__name__)
def load_public_key():
"""Load Eartho public key"""
return serialization.load_pem_public_key(EARTHO_PUBLIC_KEY.encode(), backend=default_backend())
def token_required(token):
"""Decorator for protected routes"""
public_key = load_public_key()
try:
decoded = jwt.decode(token, public_key, algorithms=["RS256"], audience=EARTHO_AUDIENCE, issuer=EARTHO_ISSUER)
return decoded
except jwt.ExpiredSignatureError:
return {'message': 'Token expired!'}
except jwt.InvalidTokenError as e:
return {'message': 'Invalid token!', 'error': str(e)}
return {'message': 'Invalid token!', 'error': str('')}
@app.route('/protected', methods=['GET'])
def protected():
token = request.headers.get('Authorization')
if not token:
return jsonify({'message': 'Token is missing!'}), 401
token = token.split(" ")[1] # Removing 'Bearer' from token string
decoded_token = token_required(token)
if 'message' in decoded_token:
return jsonify(decoded_token), 401
return jsonify({'message': 'This is a protected route.', 'user': decoded_token})
def main():
# Simulating request to the protected route
valid_token = "YOUR_VALID_TOKEN"
headers = {'Authorization': f'Bearer {valid_token}'}
response = requests.get('http://127.0.0.1:5000/protected', headers=headers)
print(response.json())
if __name__ == "__main__":
main()
This plugin adds support for using JWT in Elysia handler
Install with:
bash
bun add @elysiajs/jwt
Then use it:
typescript
import { Elysia } from 'elysia'
import { jwt } from '@elysiajs/jwt'
const app = new Elysia()
.use(
jwt({
name: 'jwt',
secret: 'Fischl von Luftschloss Narfidort'
})
)
.get('/sign/:name', async ({ jwt, cookie: { auth }, params }) => {
auth.set({
value: await jwt.sign(params),
httpOnly: true,
maxAge: 7 * 86400,
path: '/profile',
})
return `Sign in as ${auth.value}`
})
.get('/profile', async ({ jwt, set, cookie: { auth } }) => {
const profile = await jwt.verify(auth.value)
if (!profile) {
set.status = 401
return 'Unauthorized'
}
return `Hello ${profile.name}`
})
.listen(3000)
Below is a guide for setting up user authentication in a Rust server application using JWTs with the jsonwebtoken
crate. This will help you secure API routes.
Step 1: Set Up Your Rust Environment Make sure that your Rust environment is correctly set up, including Cargo, Rust’s package manager and build system. If Rust is not installed, visit the official Rust website for installation instructions.
Step 2: Add Dependencies Add the jsonwebtoken
crate along with serde
and warp
to handle the web server functionality and JWT parsing. Update your Cargo.toml
as follows:
[dependencies]
jsonwebtoken = "7"
serde = { version = "1.0", features = ["derive"] }
warp = "0.3"
tokio = { version = "1", features = ["full"] }
Step 3: Define JWT Secret and Claims Struct In your main Rust file (main.rs
), define a secret key for JWT signing and a struct to represent the claims:
use jsonwebtoken::{decode, encode, DecodingKey, EncodingKey, Header, Validation};
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]
struct Claims {
sub: String, // Subject (who this token is about)
company: String,
exp: usize, // Expiration time (as seconds since the Unix epoch)
}
const SECRET_KEY: &str = "your_secret_key_here";
Step 4: Token Verification Function Implement a function to verify the JWT token from the Authorization header:
fn verify_token(token: &str) -> Result
Step 1: Install the jwt gem First, install the jwt gem using RubyGems. If you haven't already installed RubyGems, you can install it from https://rubygems.org/pages/download.
gem install jwt
This command will install the jwt gem, which provides functionality for encoding and decoding JSON Web Tokens (JWTs) in Ruby applications.
Step 2: Configure Your Web Server Assuming you're using a Ruby web framework like Sinatra or Ruby on Rails, set up a basic server. If you're using another framework, the setup will be similar but may require different syntax.
require 'sinatra'
# Assuming you're using Sinatra
get '/' do
'Hello, world!'
end
Step 3: Define a Route to Verify Eartho Tokens Create a protected route that requires a valid JWT for access. You'll extract the JWT from the Authorization header, verify it, and then proceed based on the verification result.
require 'sinatra'
require 'jwt'
# Your Eartho project's JWT configuration
EARTHO_ISSUER = 'https://one.eartho.world/'
EARTHO_AUDIENCE = ''
EARTHO_PUBLIC_KEY = ""
def load_public_key
# Load Eartho public key
OpenSSL::PKey.read(EARTHO_PUBLIC_KEY)
end
def token_required(token)
public_key = load_public_key
begin
decoded = JWT.decode(token, public_key, true, { algorithm: 'RS256', audience: EARTHO_AUDIENCE, iss: EARTHO_ISSUER })
decoded.first
rescue JWT::ExpiredSignature
{ 'message' => 'Token expired!' }
rescue JWT::DecodeError
{ 'message' => 'Invalid token!' }
end
end
get '/protected' do
token = request.env['HTTP_AUTHORIZATION']
return { 'message' => 'Token is missing!' }.to_json if token.nil?
token = token.split(' ').last # Removing 'Bearer' from token string
decoded_token = token_required(token)
return decoded_token.to_json if decoded_token.is_a? Hash
{ 'message' => 'This is a protected route.', 'user' => decoded_token }.to_json
end
This code defines a route '/protected' that expects a JWT token in the Authorization header. It verifies the token using the provided Eartho public key and returns the decoded token if valid.
This is a basic setup for verifying JWT tokens in a Ruby web application. Depending on your specific requirements and framework, you may need to adjust the implementation accordingly.
Step 1: Install Packages First, install the necessary NuGet packages for JWT token handling. You'll need the System.IdentityModel.Tokens.Jwt
package for JWT functionality and Microsoft.AspNetCore.Authentication.JwtBearer
for handling JWT-based authentication in ASP.NET Core applications.
dotnet add package System.IdentityModel.Tokens.Jwt
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
Step 2: Configure Your ASP.NET Core Application In your ASP.NET Core application, configure JWT authentication in the Startup.cs
file. Add the necessary services and middleware to enable JWT-based authentication.
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.IdentityModel.Tokens;
using System.Text;
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
// Add JWT authentication
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = "JwtBearer";
options.DefaultChallengeScheme = "JwtBearer";
}).AddJwtBearer("JwtBearer", jwtBearerOptions =>
{
jwtBearerOptions.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("your_secret_key_here")),
ValidateIssuer = true,
ValidIssuer = "https://one.eartho.world/",
ValidateAudience = false, // Change to true if you want to validate the audience
//ValidAudience = "", // Set your audience here if you want to validate it
ValidateLifetime = true // Change to false if you don't want to validate the token's lifetime
};
});
services.AddControllers();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
// Enable authentication
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
Step 3: Define a Controller to Verify Eartho Tokens Create a controller with a protected route that requires a valid JWT for access. Extract the JWT from the Authorization header, verify it, and then proceed based on the verification result.
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Text;
[Route("[controller]")]
[ApiController]
public class ProtectedController : ControllerBase
{
private readonly string _issuer = "https://one.eartho.world/";
[HttpGet]
[Authorize]
public IActionResult Get()
{
var token = HttpContext.Request.Headers["Authorization"].ToString().Replace("Bearer ", "");
var tokenHandler = new JwtSecurityTokenHandler();
try
{
var key = Encoding.ASCII.GetBytes("your_secret_key_here");
tokenHandler.ValidateToken(token, new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = true,
ValidIssuer = _issuer,
ValidateAudience = false, // Change to true if you want to validate the audience
//ValidAudience = "", // Set your audience here if you want to validate it
ValidateLifetime = true // Change to false if you don't want to validate the token's lifetime
}, out var validatedToken);
var jwtToken = (JwtSecurityToken)validatedToken;
var user = new
{
Name = jwtToken.Subject
};
return Ok(new { Message = "This is a protected route.", User = user });
}
catch (Exception ex)
{
return Unauthorized(new { Message = "Invalid token!", Error = ex.Message });
}
}
}
This code defines a controller with a route '/protected' that expects a JWT token in the Authorization header. It verifies the token using the provided secret key and returns the decoded token if valid.
These are the basic steps to set up JWT token verification in a C# ASP.NET Core application. You may need to adjust the implementation according to your specific requirements and architecture.
First, install the JWT library using Composer. If you don't already have Composer, you can install it from https://getcomposer.org. Run the following command to install the required libraries:
bashCopy codecomposer require lcobucci/jwt guzzlehttp/guzzle
Assuming you're using a basic PHP setup with Apache or Nginx, create a basic PHP script for your server.
Create a script to handle JWT verification. Here's an example script:
phpCopy code<?php
require 'vendor/autoload.php'; // Load Composer's autoloader
use Lcobucci\JWT\Configuration;
use Lcobucci\JWT\Signer\Rsa\Sha256;
use Lcobucci\JWT\Signer\Key\InMemory;
use Lcobucci\JWT\Validation\Constraint\IssuedBy;
use Lcobucci\JWT\Validation\Constraint\PermittedFor;
use Lcobucci\JWT\Validation\Constraint\SignedWith;
define('EARTHO_ISSUER', 'https://one.eartho.world/');
define('EARTHO_AUDIENCE', '<EARTHO_CLIENT_ID>'); // Take it from the security tab in creator.eartho.io
define('EARTHO_PUBLIC_KEY', '<EARTHO_PUBLIC_KEY>'); // Take it from the security tab in creator.eartho.io
function load_public_key() {
// Load Eartho public key
return file_get_contents(EARTHO_PUBLIC_KEY);
}
function token_required($token) {
// Function to verify JWT
$public_key = load_public_key();
$config = Configuration::forAsymmetricSigner(
new Sha256(),
InMemory::plainText(''), // Empty private key as we are not signing
InMemory::plainText($public_key)
);
$token = $config->parser()->parse($token);
$constraints = [
new IssuedBy(EARTHO_ISSUER),
new PermittedFor(EARTHO_AUDIENCE),
new SignedWith($config->signer(), InMemory::plainText($public_key))
];
if (!$config->validator()->validate($token, ...$constraints)) {
return ['message' => 'Invalid token!'];
}
return $token->claims()->all();
}
// Step 4: Create a Protected Route
if ($_SERVER['REQUEST_METHOD'] === 'GET' && $_SERVER['REQUEST_URI'] === '/protected') {
$headers = apache_request_headers();
if (!isset($headers['Authorization'])) {
header('Content-Type: application/json');
http_response_code(401);
echo json_encode(['message' => 'Token is missing!']);
exit;
}
$token = str_replace('Bearer ', '', $headers['Authorization']);
$decoded_token = token_required($token);
if (isset($decoded_token['message'])) {
header('Content-Type: application/json');
http_response_code(401);
echo json_encode($decoded_token);
exit;
}
header('Content-Type: application/json');
echo json_encode(['message' => 'This is a protected route.', 'user' => $decoded_token]);
exit;
}
?>