Redirecting to Authorization Endpoint

First you need to generate a URL to the authorization endpoint for the Authorization Server and redirect the user.

<?php

$query = http_build_query([
    'client_id' => '',
    'response_type' => 'code',
    'response_mode' => 'query',
    'scope' => 'openid profile',
    'redirect_uri' => 'http://localhost/login_callback.php',
    'state' => $state,
    'nonce' => $nonce
]);

header('Location: ' . 'https://{yourOktaDomain}}/oauth2/default/v1/authorize?'.$query);

The nonce should be a generated string such as UUID, and the state can be any string representing state of the application.

Exchange Auth Code

After a successful login from the redirect, a code will be present in the request object.

This code should be placed in the file specified for your redirect_uri from the previous step.

<?php

if(array_key_exists('state', $_REQUEST) && $_REQUEST['state'] !== $state) {
    throw new \Exception('State does not match.');
}

if(array_key_exists('code', $_REQUEST)) {
    $exchange = exchangeCode($_REQUEST['code']);
}

function exchangeCode($code) {
    $authHeaderSecret = base64_encode( ':' );
    $query = http_build_query([
        'grant_type' => 'authorization_code',
        'code' => $code
    ]);
    $headers = [
        'Authorization: Basic ' . $authHeaderSecret,
        'Accept: application/json',
        'Content-Type: application/x-www-form-urlencoded',
        'Connection: close',
        'Content-Length: 0'
    ];
    $url = 'https://{yourOktaDomain}}/oauth2/default/v1/token?' . $query;
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_POST, 1);
    $output = curl_exec($ch);
    $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    if(curl_error($ch)) {
        $httpcode = 500;
    }
    curl_close($ch);
    return json_decode($output);
}

The result of this will provide you with a JWT for that user.

$jwt = $exchange->access_token;

Once you have the JWT, you should verify it using this guide

Handling Errors

If an error is present in the login, an error query parameter will be present.

if(array_key_exists('error', $_REQUEST)) {
    throw new \Exception($_REQUEST['error']);
}