OAuth is commonly used as a way for web surfers to log into third party web sites using their Google, Facebook or Twitter accounts.
In the example Basics of Authentication for the GitHub OAuth they create a Ruby server to show the Web Application Flow for using OAuth with GitHub.
Basically the Web Flow consists of three parts:
The different GitHub Java-API’s all require the Access-Token. Accordingly we need to get the Access-Token first before we’re able to use those libraries.
In the following example we want to use Java, the Spark Web Framework, the Rest-client Unirest and the template engine freemarker to achieve the same functionality of the Ruby server in the Basics of Authentication Guide.
The following code can also be found on GitHub.
First register a new OAuth application.
Use http://localhost:4567/callback
as the Authorization callback URL. The Client ID and Client Secret should be stored as environment variables:
export GH_BASIC_CLIENT_ID=97xor4b13d58cc5a5b42
export GH_BASIC_SECRET_ID=553foobd8f4c06c211232barbaze15e988405b42
Create the template index.ftl
:
<p>
We're going to now talk to the GitHub API. Ready?
<a href="https://github.com/login/oauth/authorize?
scope=user:email&client_id=${client_id}">
Click here
</a> to begin!</a>
</p>
<p>
If that link doesn't work, remember to provide your own
<a href="/v3/oauth/#web-application-flow">Client ID</a>!
</p>
Create the FreeMarkerTemplateEngine
class, that will render the template:
public class FreeMarkerTemplateEngine extends TemplateEngine {
private Configuration config;
protected FreeMarkerTemplateEngine() {
this.config = createFreemarkerConfiguration();
}
@Override
public String render(ModelAndView modelAndView) {
StringWriter sw = new StringWriter();
try {
Template t = config.getTemplate(modelAndView.getViewName());
t.process(modelAndView.getModel(), sw);
} catch (Exception e) {
e.printStackTrace();
}
return sw.toString();
}
private Configuration createFreemarkerConfiguration() {
Configuration c = new Configuration();
c.setClassForTemplateLoading(FreeMarkerTemplateEngine.class, "freemarker");
return c;
}
}
Create the route displaying the template. Provide the client_id
to the template.
get("/", (request, response) -> {
Map<String, Object> attributes = new HashMap<>();
attributes.put("client_id", System.getenv("GH_BASIC_CLIENT_ID"));
return new ModelAndView(attributes, "index.ftl");
}, new FreeMarkerTemplateEngine());
Create the callback route and access the provided session code (code
):
get("/callback",(request, response) -> {
String sessionCode = request.queryParams("code");
});
Use the session code to
String accessToken = Unirest.post("https://github.com/login/oauth/access_token")
.header("accept", "application/json")
.field("client_id", System.getenv("GH_BASIC_CLIENT_ID"))
.field("client_secret", System.getenv("GH_BASIC_SECRET_ID"))
.field("code", sessionCode)
.asJson().getBody().getObject()
.get("access_token").toString();;
With the access-token we’re ready to use the GitHub API. For example to get the username for an access-token:
String username = Unirest.get("https://api.github.com/user?access_token="+
accessToken).asJson().getBody().getObject().get("login").toString();
But you should probably use a specialized library instead of accessing the API through REST.