d12g

Blog von Daniel Grewing

Microservices (Teil 2)

17. Mai 2015 Softwareentwicklung

In meinem letzten Beitrag habe ich eine Einführung in den Architekturstil der Microservices gegeben. Am Beispiel der Webanwendung “Zetteln” habe ich gezeigt, wie man eine Webanwendung in verschiedene Komponenten aufteilen kann und welche Vorteile sich dadurch ergeben. In diesem Beitrag möchte ich meine Idee der Kommunikation der Komponenten untereinander anhand von Codebeispielen vorstellen.

Die Anmeldemaske von Zetteln wird mit einer einfachen HTML-Seite umgesetzt.

<form class="form-signin" id= "loginform">
  <h2 class= "form-signin-heading">Anmelden </h2>
  <div class= "alert alert-danger" role ="alert" style=" display: none;" id="alert_login_error" >
    Logindaten nicht korrekt
  </ div>
  <label for= "inputEmail" class ="sr-only"> E-Mail</ label>
  <input type= "email" id ="inputEmail" class= "form-control" placeholder="Email address" required autofocus>
  <label for= "inputPassword" class ="sr-only"> Passwort</label >
  <input type= "password" id ="inputPassword" class= "form-control" placeholder="Password" required>
  <button class= "btn btn-lg btn-primary btn-block" type="button" id="loginsubmit" >Login </button>
</form >

Die Überprüfung der Anmeldedaten wird von einer jQuery-Funktion ausgelöst. Da die jQuery-Funktion einen Ajax-Request auf eine andere Webanwendung durchführt, muss über ein Callback mit JSONP gearbeitet werden, damit keine Cross-Seite Exception von JavaScript ausgelöst wird.

$("#loginsubmit").click( function(){
  $.ajax({
    type: 'GET',
    url: 'http://localhost:8090/login',
    data: "email="+$("#inputEmail" ).val()+"&password=" +$("#inputPassword" ).val(),
    dataType: 'jsonp',
    success: function(responseData, textStatus, jqXHR){
      var uuid = responseData.uuid;
      if (uuid != '' ){
        location.href= "http://localhost:8088/zetteln/index/login?uuid=" +uuid;
      }
      else{
        $( "#alert_login_error").show();
      }
    },
    error: function (responseData, textStatus, errorThrown){
      $( "#alert_login_error").show();
    }
  });
});

Über den Callback wird der Benutzer verifiziert. Die Daten werden von der Spring Boot Komponente überprüft und an den jQuery Aufruf zurückgegeben:

@RestController
@RequestMapping("/login" )
public class LoginController {
  @RequestMapping(method=RequestMethod.GET)
  public @ResponseBody String login(@RequestParam (value="email" ) String email, @RequestParam(value="password" ) String password, @RequestParam(value= "callback") String callback) {
    String returnValue = callback + "(" +checkUser(email, password)+")";
    return returnValue ;
  }

  private String checkUser(String email , String password){
    String uuid = "";
    if (email .equals("daniel.grewing@googlemail.com" ) && password.equals("zetteln" )){
      uuid = "89dda95851504c6eb9ae99b9270e438b" ;
    }
  return "{\"uuid\":\"" +uuid +"\"}" ;
  }
}

In der Methode checkUser erfolgt die eigentliche Abfrage der Benutzerdaten. Sie ist hier nur beispielhaft umgesetzt und würde sonst über eine Datenbankabfrage laufen.

Wenn die Login Komponente die Daten verifiziert hat erfolgt die Weiterleitung zur eigentlichen Zetteln-Anwendung mittels location.href. Die Benutzerdaten können dann nochmal verifiziert werden.

Diese Codebeispiele zeigen die Kommunikation der drei Komponenten meiner kleinen Anwendung in einer Microservice-Architektur nur anssatzweise. Über das Thema Sichheit müsste ich mir nochmal einigen Gedanken machen und diese umsetzen.