Skip to content

Instantly share code, notes, and snippets.

@hardyscc
Last active September 21, 2023 10:36
Show Gist options
  • Save hardyscc/c087f374bf7ed55c6cb6c47ce3cffec7 to your computer and use it in GitHub Desktop.
Save hardyscc/c087f374bf7ed55c6cb6c47ce3cffec7 to your computer and use it in GitHub Desktop.
Keycloak Sample - react type-graphql react-router-dom react-keycloak keycloak-js keycloak-connect
import { InMemoryCache } from "apollo-cache-inmemory";
import { ApolloClient } from "apollo-client";
import { setContext } from "apollo-link-context";
import { createHttpLink } from "apollo-link-http";
import { keycloak } from "./keycloak";
const httpLink = createHttpLink({
uri: "http://localhost:4000/graphql"
});
const authLink = setContext((_, { headers }) => {
// get the authentication token from local storage if it exists
const token = keycloak.token;
// return the headers to the context so httpLink can read them
return {
headers: {
...headers,
authorization: token ? `Bearer ${token}` : ""
}
};
});
export const client = new ApolloClient({
link: authLink.concat(httpLink),
cache: new InMemoryCache()
});
import { AuthChecker } from "type-graphql";
import { MyContext } from "../types/MyContext";
export const authChecker: AuthChecker<MyContext> = ({ context }, roles) => {
const grant = context.req.kauth.grant;
if (grant == undefined) {
console.log("grant is undefined");
}
if (grant && grant.access_token) {
// if no role given
if (roles.length == 0) {
return true;
}
// if match any of the roles
for (let i in roles) {
if (grant.access_token.hasRole(roles[i])) {
return true;
}
}
}
return false;
};
@Resolver()
export class HelloResolver {
@Authorized()
@Query(() => String)
hello(): string {
return "Hello World";
}
}
var keycloak = new Keycloak({});
(async () => {
const app = Express();
app.use(keycloak.middleware());
const schema = await buildSchema({
authChecker
// ...
});
// ...
})();
import { Response } from "express";
import { GrantedRequest } from "keycloak-connect";
export interface MyContext {
req: GrantedRequest;
res: Response;
}
import React from "react";
import { useKeycloak } from "react-keycloak";
import { Route, RouteProps } from "react-router";
export const PrivateRoute: React.FC<RouteProps> = ({
component: Component,
render,
...rest
}) => {
const [keycloak, initialized] = useKeycloak();
return (
<Route
{...rest}
render={props => {
if (!initialized) {
return <div>Keycloak initialing...</div>;
}
if (!keycloak.authenticated) {
keycloak.login();
return <div>redirect to login</div>;
}
if (Component) {
return <Component {...props} />;
}
return render ? render(props) : null;
}}
/>
);
};
import React from "react";
import { useKeycloak } from "react-keycloak";
import { Link } from "react-router-dom";
export const Welcome = () => {
const [keycloak] = useKeycloak();
return (
<div>
<p>Welcome</p>
<Link to="dexa">Dexa Report</Link>
{keycloak.authenticated && (
<div>
<button onClick={() => keycloak.logout()}>Logout</button>
</div>
)}
</div>
);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment