Showing posts with label guest post. Show all posts
Showing posts with label guest post. Show all posts

Friday, January 13, 2017

Understanding AOT and Dynamic Components

This is a guest post from Sean Landsman at ag-Grid. Sean is the lead engineer on ag-Grid's Angular integration. -- Stephen Fluin


Motivation

ag-Grid is an enterprise datagrid that works with Angular. As ag-Grid works with many frameworks, the internals of the grid had to allow for Angular rendering inside the grid despite ag-Grid not being written in Angular itself. This was done using Angular Dynamic Components and we managed to do it while still supporting AOT. This blog details what we learnt along the way.

The Setup

To explain we present a simple sample application that isolates what we are trying to do. In our example below we are going to develop two main Modules - one will be a Library (in our case this was ag-Grid) that will display an array of dynamically created Components (similar to how ag-Grid displays Angular components inside the grid's cells), and the other will be our actual Application.
The end result will be look like this:




You can find all the code for this example over at GitHub, and the live example over at GitHub.io
One further note - when we return to "user" below, we are referring to a user (or client) of the Library we're writing.

The Library

Our Library is going to be a simple one - all it does is display an array of dynamically created Angular Components. The main component looks like this:

@Component({
    selector: 'grid-component',
    template: `
        <div class="row" *ngFor="let cellComponentType of cellComponentTypes">
            <div class="col-lg-12">
                <grid-cell [componentType]="cellComponentType"></grid-cell>
            </div>
        </div>
    `
})
export class Grid {
    @Input() componentTypes: any;

    cellComponentTypes: any[] = [];

    addDynamicCellComponent(selectedComponentType:any) {
        this.cellComponentTypes.push(selectedComponentType);
    }
}

As you can see it's a pretty simple component - all it does is display the current cellComponentTypes. These are the user supplied components, and they can be any Angular Component.

The interesting part of the Library is in the Cell Component:

@Component({
    selector: 'grid-cell',
    template: ''
})
export class Cell implements OnInit {
    @Input() componentType: any;

    constructor(private viewContainerRef: ViewContainerRef,
                private cfr: ComponentFactoryResolver) {
    }

    ngOnInit() {
        let compFactory = this.cfr.resolveComponentFactory(this.componentType);
        this.viewContainerRef.createComponent(compFactory);
    }
}

You'll notice that we don't have a template here - that's deliberate as the Cell doesn't have any
    content of its own - all it does is serve up the user supplied Component. The important part of this Component are
    these two lines:

let compFactory = this.cfr.resolveComponentFactory(this.componentType);

This line asks the ComponentFactoryResolver to find the ComponentFactory for the provided
    Component. We'll use this factory next to create the actual component:

this.viewContainerRef.createComponent(compFactory);

And that's all there is to it from the Library Component side of things - we find the factory for the Component, and
    then create a new instance of the Component. Easy!

For this to work we need to tell Angular's AOT Compiler to create factories for the user provided Components, or ComponentFactoryResolver won't find them. We can make use of NgModule.entryComponents for this - this will ensure that the AOT compiler creates the necessary factories, but for you purposes there is an easier way, especially from a users perspective:

@NgModule({
    imports: [
        BrowserModule,
        FormsModule
    ],
    declarations: [
        Grid,
        Cell
    ],
    exports: [
        Grid
    ]
})
export class GridModule {
    static withComponents(components: any[]) {
        return {
            ngModule: GridModule,
            providers: [
                {provide: ANALYZE_FOR_ENTRY_COMPONENTS, useValue: components, multi: true}
            ]
        }
    }
}

By making use of ANALYZE_FOR_ENTRY_COMPONENTS here, we are able to add multiple components to the NgModule.entryComponents
    entry dynamically, in a user friendly way.

The Application

From the application side of things, the first thing we need to do is create the components we want to use in the Library - these can be any valid Angular Component. In our case we have three similar Components:

@Component({
    selector: 'dynamic-component',
    template: '<div class="img-rounded" style="background-color: lightskyblue;margin: 5px"> Blue Dynamic Component! </div>',
})
export class BlueDynamicComponent {
}

All these components do is display a little styled text.
To register these in both our Application, and in the Library, we need to switch to the Application Module:

@NgModule({
    imports: [
        BrowserModule,
        FormsModule,
        GridModule.withComponents([
            BlueDynamicComponent,
            GreenDynamicComponent,
            RedDynamicComponent
        ])
    ],
    declarations: [
        AppComponent,
        BlueDynamicComponent,
        GreenDynamicComponent,
        RedDynamicComponent
    ],
    bootstrap: [AppComponent]
})
export class AppModule {
}


We declare our Components in the usual way, but we additionally need to register them with the Library (remember,
    this is the part where they'll be added to the
    Library's NgModule.entryComponent entry). We do this in this part of the module:

GridModule.withComponents([
    BlueDynamicComponent,
    GreenDynamicComponent,
    RedDynamicComponent
])


Finally, we can take a look at the main Application Component:

@Component({
    selector: 'my-app',
    template: `
        <div class="container-fluid">
            <div class="page-header">
                <h1>Creating AOT Friendly Dynamic Components with Angular
</div>
            <div class="row">
                <div class="col-lg-12">
                    <div class="panel panel-default">
                        <div class="panel-heading">Application Code</div>
                        <div class="panel-body">
                            <div class="input-group">
                                <span class="input-group-btn">
                                    <button type="button" class="btn btn-primary" (click)="grid.addDynamicCellComponent(selectedComponentType)">Add Dynamic Grid component
    </span>

                                <select class="form-control" [(ngModel)]="selectedComponentType">
                                    <option *ngFor="let cellComponentType of componentTypes" [ngValue]="cellComponentType">{{cellComponentType.name}}
    </select>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            <div class="row">
                <div class="col-lg-12">
                    <div class="panel panel-default">
                        <div class="panel-heading">Library Code</div>
                        <div class="panel-body">
                            <grid-component #grid></grid-component>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    `
})
export class AppComponent implements OnInit {
    @Input() componentTypes: any[] = [BlueDynamicComponent, GreenDynamicComponent, RedDynamicComponent];
    @Input() selectedComponentType: any;

    ngOnInit(): void {
        // default to the first available option
        this.selectedComponentType = this.componentTypes ? this.componentTypes[0] : null;
    }
}

It may look like theres a lot going on here, but the bulk of the template is to make it look pretty. The key parts of this Component are:

<button type="button" class="btn btn-primary" (click)="grid.addDynamicCellComponent(selectedComponentType)">Add Dynamic Grid component

This will ask the Library to add a create a new instance of the supplied Component, and in turn render it.

<grid-component #grid></grid-component>


And this line is our Library Component.

That's it - easy to write and use (from both an Application and Library perspective), and AOT (and JIT!) friendly.

Benefits of using AOT

The speed and size of the resulting application when using AOT can be significant. In our ag-grid-ng2-example project, we estimate the size of the resulting application went from 3.9Mb down to 2.4Mb - a reduction of just under 40%, without optimising for size or being particularly aggressive with rollup.

Speed-wise, the loading time when using AOT is significantly more responsive on startup - this makes sense given that Angular doesn't have to compile all the code once again. Take a look at the examples project and try both the JIT and AOT versions out for yourself!

There's so much more you can do if you decide to combine Angular Components with ag-Grid - powerful functionality, fast grid and easy configuration. What are you waiting for?!

Tuesday, December 13, 2016

Ok... let me explain: it's going to be Angular 4.0, or just Angular

This is a guest blog post by Juri Strumpflohner. Juri is a full-stack developer, architect and tech lead with a passion for frontend development, especially Angular. Juri writes technical articles on his personal blog and is the author of some online video courses. He also likes to engage and help the Angular community on Twitter, so follow him for more interesting news and articles around Angular and frontend web development. Juri was an attendee of NG-BE, Belgium’s first Angular conference last week and did a better job covering our announcements than we would have done, so we are cross-posting his blog post here.

Update: This blog was updated by the Angular team on 2017-01-26 to reflect the latest naming standards.


At the 8th and 9th of December 2016 was NG-BE, Belgium’s first Angular conference. Igor Minar (Angular lead dev) attended as the keynote speaker with some interesting announcements regarding Angular’s release schedule. Please read the entire post, there are a couple of important things.
Igor was extremely open and transparent about the announcement and even about the way of presenting it. He basically created the presentation openly the day before the conference:


So here it is:

Angular 4, March 2017, Backwards Compatible w/ Angular 2

Why Angular 4?? Why even Angular 3?? What is going on?

Angular uses SEMVER

Back in September when the new Angular was finally released, the Angular team also announced they will switch to Semantic Versioning (SEMVER).
As the name already explains, Semantic Versioning is all about adding meaning to version numbers. This allows developers to not only reason about any upgrade we do, but we can even let tools such as NPM do it in a automatic and safe manner for us.
A semantic version consists of three numbers:

2.3.1 - major = breaking change, minor = new features, not breaking, patch = bugfixes, not breaking

Whenever you fix a bug and release it, you increase the last number, if a new feature is added, you increase the second number and whenever you release a breaking change you increase the first number.
“A breaking change happens whenever you as a developer and consumer of a library, have to step in and adjust your code after a version upgrade.”
So what does this mean for the Angular team? As with every evolving piece of software, breaking changes will occur at some point. For example, giving a compiler error for existing application bugs that went unnoticed with the previous compiler version, anything, that will break an existing application when upgrading Angular, requires the team to bump the major version number.
Just to be clear, as also Igor mentioned in his talk. Right now, even just upgrading Angular’s TypeScript dependency from v1.8 to v2.1 or v2.2 and compile Angular with it, would technically cause a breaking change. So they’re taking SEMVER very, very seriously.

Breaking changes don’t have to be painful!

People that have been following the Angular community for a while, definitely know what I’m talking about. We went from Angular 1 to Angular 2, and it was a total breaking change, with new APIs, new patterns. That was obvious: ultimately Angular 2 was a complete rewrite. (Even though there are upgrade options for you available)
Changing from version 2 to version 4, 5, … won’t be like changing from Angular 1. It won’t be a complete rewrite, it will simply be a change in some core libraries that demand a major SEMVER version change. Also, there will be proper deprecation phases to allow developers to adjust their code.
Internally at Google, the Angular team uses a tool for handling automatic upgrades, even of breaking changes. This is still something that has to be planned in more detail, but the team is working hard on making this tool generally available, most probably in 2017 in time for version 5.

It’s just “Angular”

As you might have already guessed, the term “Angular 2” is also kind of deprecated once we get to version 4, 5 etc. That said, we should start naming it simply “Angular” without the version suffix.
“It’s just #angular”
Also, we should start avoiding GitHub/NPM libraries prefixed with ng2- or angular2-.


Naming guidelines

Basically from now on, you should name versions 2.0.0 or later of Angular simply “Angular”. Try to avoid using the version number, unless it is really necessary to disambiguate.

Three simple guidelines:
  • Use “Angular” for versions 2.0.0 and later (e.g. “I’m an Angular developer”, “This is an Angular meetup”, “The Angular ecosystem is growing quickly”)
  • Use "AngularJS" to describe versions 1.x or earlier
  • Use the version number “Angular 4.0” "Angular 2.4" when needed to talk about a specific release (e.g. when talking about a newly introduced feature - “This is an introduction to feature X, introduced in Angular 4”, “I’m proposing this change for Angular 5”)
  • Use full semver version when reporting a bug (e.g. “This issue is present as of Angular 2.3.1”)
All the docs - even for AngularJS - will be aligned to this in the coming weeks. Also in blog articles, courses, books, if you are targeting a very specific version of Angular for a reason, consider adding a header line which states that:
“This article uses Angular v2.3.1.”
That helps avoid confusion for your readers, especially when you are writing about specific APIs.

Why not version 3 then?

The core Angular libraries live in one single GitHub repository at github.com/angular/angular. All of them are versioned the same way, but distributed as different NPM packages:

@angular/core v2.3.0, @angular/compiler v2.3.0, @angular/compiler-cli v2.3.0, @angular/http v2.3.0, in bold: @angular/router v3.3.0

Due to this misalignment of the router package’s version, the team decided to go straight for Angular v4. In this way again, all the core packages are aligned which will be easier to maintain and help avoid confusion in the future.
Also it is important to understand how Angular is being used and integrated inside Google (Igor speaks about this here in his keynote). All Google applications use Angular version equal to the current GitHub’s master branch of the Angular repository. Whenever a new commit lands in master, it will be integrated into Google’s single, giant mono-repo, where also other products such as Maps, Adsense etc. live. As a consequence all of the projects using Angular internally at Google will run their extensive test suites against this new version. This makes the team very confident to cut a new release, since it will contain the exact combination of versions of Angular packages that have been already battle tested inside Google. Thus, having aligned versions totally makes sense and makes it easier to maintain them over time, which in turn helps the team be more productive in releasing new features.

Tentative release schedule

The fact that breaking changes will arrive, doesn’t mean they will arrive every other week. The Angular team committed to time based releases that occur in three cycles:
  • patch releases every week,
  • 3 monthly minor release after each major release and
  • a major release with easy-to-migrate-over breaking changes every 6 months.
The next 3 months will be dedicated to finalizing Angular 4.0.0.

Weekly breakdown of all releases starting with 4.0.0-beta.0, ending with 4.0.0 on March 1, 2017

After Angular 4.0.0, this will be the tentative schedule for further releases:

Version 4 in March 2017, Version 5 in September/October 2017, Version 6 in March 2018, Version 7 in September/October 2018

Video: See the announcement yourself



Conclusion

There are two main important messages here:
  • don’t worry about version numbers
  • we do need to evolve Angular in order to avoid another Angular 1 to Angular 2 change, but we should do it together as a community in a transparent, predictable and incremental way.
Also, I’d like to thank Igor for being so open at presenting this data, especially since he knows what a sensitive topic breaking changes are and have been in the past. This means a lot and I hope that the community will realize why all these changes are good for everyone involved.

Wednesday, November 2, 2016

Easy Angular Authentication with JSON Web Tokens

Easy Angular Authentication with JSON Web Tokens

Stateless authentication is a great fit for Angular apps. In this post, guest-blogger Ryan Chenkie from Auth0 talks about implementing it using JSON Web Tokens. -- Victor Savkin


TL;DR: Single page apps--like the ones we build with Angular--present a few challenges when it comes to authentication. In general, traditional session-based authentication isn't a good fit for SPAs that use data APIs because it necessitates state on the server. A better way to do authentication in Angular apps (and SPAs in general) is with JSON Web Tokens (JWTs). Read on to find out more about JWTs, or check out Angular 2 Tour of Secret Heroes to see an example of a full Angular 2 app with user authentication.
Pretty well all non-trivial applications require some way of dealing with user authentication and authorization. This can be fairly straight-forward in round-trip applications because all that is really needed when a user logs in is to check their credentials against a database, save a session for them on the server, and return a cookie to be saved in their browser. The cookie is then sent along in subsequent requests to the server and is checked against the session to verify their identity.
This works well for "traditional" applications, but it isn't a great fit for single page apps that use data APIs. Since SPAs are client-side apps, dealing with the notion of the user's authentication state is also a bit trickier. Essentially what it boils down to is that we need some indication of the user's authentication state even though the backends that we rely on should remain stateless. This isn't a problem in round-trip apps because the HTML and data that get returned to the user is constructed on the backend, which is exactly the place that a stateful check can be done to figure out whether or not the user is currently logged in. When we use REST APIs for data however, a stateful session that tracks authentication is bad practice.

JSON Web Tokens - Stateless Authentication in Angular Apps

A great way to do stateless authentication in an Angular app is to use JSON Web Tokens (JWT). JWT is an open standard (RFC 7519), and likely the most compelling reason to choose it as an authentication mechanism is that it can be used to transmit arbitrary data as a JSON object. Since JWTs are digitally signed with a secret key that lives only on the server, we can rest assured that the information in the token can't be tampered with at any point. If the payload in the JWT were to be tampered with, the token would become invalid, which means it wouldn't be able to get past any checkpoints on the server. This makes JWT the perfect mechanism for transmitting information about a user and it gives us a distinct advantage: we can include everything required for our API to know who the user is and what level of access they should have, and the API doesn't need to know a single thing about them prior to the JWT arriving.
So what does a JWT look like? Here's an example:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
JWTs contain three parts, and each of them is tacked together with a dot separator. The three parts are:

Header

Where we define the algorithm used to sign the token, as well as the token type.

Payload

The meat of the JWT. This is where we keep a JSON object of all the claims we want. Claims can include those that are registered in the JWT spec, as well as any arbitrary data we want.

Signature

The signature is where the signing action happens. To get the signature, we take the Base64URL encoded header, tack the Base64URL encoded payload next to it, and run that string along with the secret key through the hashing algorithm we've chosen. For the token to properly decode on the backend, it needs to have exactly this form, which means that if someone tries to change any of the information contained within, they'll be out of luck.
We can see this token decoded with Auth0's open source JWT debugger.
angular jwt authentication
It should be noted that although JWTs are digitally signed, they are not encrypted. While the digital signature ensures that the content of a JWT cannot be tampered with, they should not be used to transmit sensitive information, as the payload can easily be decoded with tools like the jwt.io debugger.

How Are JWTs Used to Authenticate Angular Apps?

For Angular apps that use data APIs, the typical scenario is this:
  1. Users send their credentials to the server which are verified against a database. If everything checks out, a JWT is sent back to them.
  2. The JWT is saved in the user's browser somehow--either by holding it in local storage or in a cookie.
  3. The presence of a JWT saved in the browser is used as an indicator that a user is currently logged in.
  4. The JWT's expiry time is continually checked to maintain an "authenticated" state in the Angular app, and the user's details are read from the payload to populate views such as the their profile.
  5. Access to protected client-side routes (such as the profile area) are limited to only authenticated users
  6. When the user makes XHR requests to the API for protected resources, the JWT gets sent as an Authorization header using the Bearer scheme, or as a cookie.
  7. Middleware on the server--which is configured with the app's secret key--checks the incoming JWT for validity and, if valid, returns the requested resources.
Fortunately for us, there are several open source libraries for both Angular 1.x and 2 which help us work with JWTs. These libraries are varied in their functionality, but some of the features we get with them are the ability to:
  • Decode the JWT and read its payload
  • Attach the JWT as an Authorization header to XHR requests
  • Have a service which exposes methods for logging in and logging out, and which checks whether the current user's JWT is expired or not

Angular 1.x

Angular 2

There are also hosted authentication solutions that can drastically simplify the process of setting up user login and signup functionality for Angular apps. This basically means that we don't need to worry about any logic for checking the user's credentials and signing tokens for them.

Authentication in Action

So we've got a list of things that our Angular apps should be doing to deal with authentication, but what does this look like in practice? Let's see an example using Angular 2.

Retrieve a JWT for a User and Save it in Local Storage

To retrieve a JWT for a user, we need to verify their credentials against a database. If everything checks out, we sign a JWT and send it back to them in the response. We can use almost any server-side language or framework for this task, and there are JWT libraries available for almost everything.
With the token signing logic set up, we need to expose an endpoint that the app can make a request to for authentication. For this, we just need to send a regular HTTP request. Placing this logic in an injectable service gives us a way to reuse it across our application.
// auth.service.ts

import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import 'rxjs/add/operator/map';

@Injectable()
export class AuthService {

  constructor(private http: Http) {}

  login(credentials) {
    this.http.post('https://my-app.com/api/authenticate', credentials)
      .map(res => res.json())
      .subscribe(
        // We're assuming the response will be an object
        // with the JWT on an id_token key
        data => localStorage.setItem('id_token', data.id_token),
        error => console.log(error)
      );
  }
}
We can then wire up a form which takes input from the user and calls the AuthService.
// login.component.ts

import { Component } from '@angular/core';
import { AuthService } from './auth.service';

interface Credentials {
  username: string,
  password: string
}

@Component({
  selector: 'login',
  template: `
    <form #f="ngForm" (ngSubmit)="onLogin(f.value)" *ngIf="!auth.loggedIn()">
      <input type="text" placeholder="username" ngControl="username">
      <input type="password" placeholder="password" ngControl="password">
      <button type="submit">Submit</button>    
    </form>
  `
})

export class LoginComponent {

  credentials: Credentials;

  constructor(private auth: AuthService) {}

  onLogin(credentials) {
    this.auth.login(credentials);
  }
}
With the login form and the authentication service in place, the user's JWT will be saved in local storage if they successfully authenticate.
You can see that we've got an *ngIf condition on the form which is looking for a loggedIn method on the AuthService. Let's put that in next.

Checking for an Unexpired Token

With stateless authentication, the only real indication for the front end that the user is "authenticated" is if they have an unexpired JWT. Certainly a more robust indication would be a check to make sure their JWT is not only unexpired, but is also still valid. However, to do this kind of check, the front end would need to know the secret key used to sign the JWT, and we really don't want to expose that. Simply checking the expiry is just fine though; if the token is invalid (in other ways than it just being expired), it won't be useful for retrieving protected API resources anyway.
To do this kind of check, we can get some help from angular2-jwt's tokenNotExpired function.
npm install angular2-jwt
// auth.service.ts

import { tokenNotExpired } from 'angular2-jwt';

...

loggedIn() {
  return tokenNotExpired();
}

...
This function simply checks the expiry date of the JWT and returns true if it is not expired.

Limit Routes to Authenticated Users

We've got a way to hide our links and navigation elements if the user either doesn't have a JWT or if their JWT is expired. However, they could still navigate by plugging in URI segments manually, so what we need is a way to limit navigation to private routes altogether. To do this we can set up an AuthGuard which checks whether the user has an unexpired JWT in local storage. We'll then apply the guard through CanActivate when we set up the routing configuration.
// auth-guard.service.ts

import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { CanActivate } from '@angular/router';
import { Auth } from './auth.service';

@Injectable()
export class AuthGuard implements CanActivate {

  constructor(private auth: Auth, private router: Router) {}

  canActivate() {
    if(this.auth.loggedIn()) {
      return true;
    } else {
      this.router.navigateByUrl('/unauthorized');
      return false;
    }
  }
}
When route navigation is requested, AuthGuard will use the AuthService to check for the presence of an unexpired JWT and, if one exists, the user will be allowed to continue to the route. If the user isn't authenticated however, they will be navigated to an "unauthorized" page.
The AuthGuard needs to be applied to whichever routes should be kept private, and this is done in the RouterConfig setup.
...

import { AuthGuard } from './auth-guard.service';

export const routes: RouterConfig = [
  { path: 'admin', component: AdminComponent, canActivate: [AuthGuard] },
  { path: 'unauthorized', component: UnauthorizedComponent }
];

...

Send Authenticated HTTP Requests

The last big step for applying authentication to our app is to have the user's JWT sent as an Authorization header in the HTTP requests they make. Since Angular 2 doesn't have any concept of HTTP interceptors like Angular 1.x does, we need to either send the header in the options object of each request, or we can wrap Http to perform this automatically. The angular2-jwt library provides AuthHttp which does the latter.
// secure-stuff.component.ts

import { Component } from '@angular/core';
import { AuthHttp, tokenNotExpired } from 'angular2-jwt';
import 'rxjs/add/operator/map';

@Component({
  selector: 'secure-stuff',
  template: `
    <button (click)="getSecureStuff()">Get Secure Stuff!</button>
  `
})

export class SecureStuffComponent {

  stuff: [];

  constructor(private authHttp: AuthHttp) {}

  getSecureStuff() {
    this.authHttp.get('https://my-app.com/api/secure-stuff')
      .map(res => res.json())
      .subscribe(
        data =>  this.stuff = data.stuff,
        error => console.log(error)
      );
  }
}
Note: Any application that uses JWT authentication should always be served over HTTPS to prevent malicious interception of the token.

Log the User Out

With stateless authentication using JWTs, logging the user out is just a matter of removing their token from local storage.
// auth.service.ts

...

@Injectable()
export class AuthService {

  ...

  logout() {
    localStorage.removeItem('id_token'); 
  }
}
You might be wondering if this is secure or not, given the fact that we're just removing the token from its holding place and it could, in reality, still be used to access the API. We've got two options to address this concern: we can set the token's expiry time to be short and/or we can implement token blacklisting on the server. With a short window of validity, the JWT can't be exploited for very long, and with blacklisting, the token's ability to access secure resources can be revoked altogether.

Full Example: Angular 2 Tour of Secret Heroes

It would be nice to see all of this authentication business in action in a working app. For that, I've put together a fork of John Papa's Tour of Heroes app (used in the Angular 2 Getting Started guide), called Angular 2 Tour of Secret Heroes. In this app, all the original heroes data--plus a set of new 'secret' heroes--has been moved to an Express server. Authentication happens with Auth0, and angular2-jwt is used for protecting routes, conditionally showing UI elements, and sending authenticated HTTP requests.

Wrapping Up

Stateless authentication has distinct advantages over traditional session-based auth. Keeping our APIs stateless makes them more agile and lets us easily port our apps to other platforms like mobile or desktop. With open source libraries, such as angular2-jwt, we can easily check for token validity and send authenticated HTTP requests with just a bit of configuration.
If you're interested in adding authentication to an Angular 1.x app, the things we went through here still apply, but there are a few differences to keep in mind. For instance, Angular 1.x has HTTP interceptors which can be used to attach the Authorization header to requests, so there's no need to wrap the $http service.
For more on Angular 1.x and 2 authentication, as well as tutorials about Angular in general, be sure to check out the Auth0 blog.

Tuesday, July 26, 2016

Fresh Guides from Victor Savkin

Since the early days of Angular 2, core team member Victor Savkin has posted his personal thoughts on the platform to his own blog. These offer an internal perspective on how someone who builds Angular thinks about its core concepts.


Victor just refreshed his older posts with the latest and greatest from the current release candidate, at a new location on vsavkin.com. He's also added some new posts.


Check out his writing on a variety of Angular topics:



Monday, July 11, 2016

Angular in China and beyond: Introducing angular.cn

Please welcome Ralph Wang (汪志成) and Rex Ye (叶志敏), joining our blog as guest authors. Ralph is a developer, author, community lead, and Angular GDE in Beijing, China. Rex is an entrepreneur based in London. Together, they have led the first localization of angular.io for developers in China. We're excited to share the newly-launched angular.cn with you! Read on to learn how they did it, and how you can get involved in bringing Angular to your locale.  --Naomi Black,  Angular TPM

Angular.cn - our official site in China

The language barrier does not stop Angular getting all the love from Chinese developers. There is new blood joining our community everyday. Some of them are newcomers, some of them have been using Angular in isolation for a long time without the support from the community. There are more than 4000 active users in our two Angular QQ chat groups, which is nothing compared to the sheer size of the whole Angular community in China. We felt that we needed to do more to enhance the influence of the community so that it could reach and help more developers.
语言的障碍并没有阻挡住中国的开发者们对Angular的热情。每天都有新人加入我们这个社区。他们有的是初学者、有的是在并没有社区支持的情况下自学了Angular很久的人。在我们两个Angular QQ群里,有4000千多名活跃的成员,但是他们仍旧远远比不上全中国Angular社区的巨大数量。我们认为我们需要加强Angular社区的影响,使得它能够影响到以及帮助更多的开发者。

We chose official document localisation as a starting point.
为此,我们选择了“翻译官方文档”作为突破口。

As a large open source project, Angular 2 is in continuous development and its documents will also be constantly updated. “Complete the localisation and leave it alone” obviously does not meet the requirement as a copy of an obsolete document could be misleading. We needed a new approach.
作为一个大型开源代码的项目,Angular 2处在不断的开发中,它的文档也将会被不断地更新。显然,“一次性翻译完,然后再也不管”的模式是无法满足需求的,一份过时的文档有时候甚至会误导读者。我们因此需要采用一种新的、能够保持持续更新的翻译方式。

The new approach we adopted is Git-based. We forked a copy of angular.io and appended the translations right next to each of the corresponding paragraphs. This way, our repository is structurally identical to angular.io. We can pull and merge any changes from angular.io easily and update our translations accordingly. Git has enabled our effective collaboration across time zones. We have created a script to hide the original text post compilation. It also allows our users to toggle the original text by simply clicking on the translated text, or by clicking the (Show English) button in the upper right corner. This is extremely handy for us and community contributors when it is time to review the work.
我们决定所采用的这种新的方式是基于GitHub的。我们开了一个angular.io库的分支,并把译文直接追加在原文之后,这样,我们资源库的架构将和angular.io的保持一致。当原文发生变更时,我们就会发现这种变化,并可以借助工具相对轻松的进行合并并及时更新译文。Github还让我们可以有效地实现跨时区的协作、也帮助协调我们两位译者的更新。填补了时区差别造成的无法及时交流的盲点。把这些源文件编译之后,我们增加了一个额外的js文件,它会按照格式上的规约,在运行期间把原文隐藏掉,还能通过点击译文来让原文重新显示出来。这种方式对于自己校对和社区的合作者协助校对至关重要。

After over a month of hard working, our localised docs site finally caught up with angular.io.
经过一个多月的高强度翻译,我们的翻译稿(并完成了第一遍校对)终于赶上了在angular.io上的官方文档的更新进度。

Without knowing anyone on the Angular team yet, we sent an email to Naomi in the evening, Beijing time. She was online early, California time, and replied right away. A few hours later, we were collaborating with the core Angular team and the project was officially under way . This is an interesting case of effective global collaboration. Ralph was in Beijing, Luke was in Shanghai, Rex was in London and Naomi was in San Francisco.
虽然我们并不认识Angular产品部门的人,但我们还是于北京时间的晚上给Naomi发了个邮件告知她我们的工作结果。加州还是当地的早晨,Naomi很快就给我们回复了热情洋溢邮件,并把我们介绍给了程路。几个小时后, 我们和Angular产品部门的核心团队的协作就开始了。这是个有趣的在全球范围内进行有效合作的案例。汪志成在北京、程路在上海、叶志敏在伦敦,而Naomi在旧金山。

We joined the Angular organisation on github,created the angular/angular-cn repository for our project, and were welcomed to Angular's doc authoring team on Slack so that we could speak to the authors directly regarding their articles and be informed of any future updates. This greatly increased the accuracy and timeliness of our translation. We were also able to contribute ideas to help the authors improve their articles.
不仅如此,Naomi还把我们加入了github上的Angular开发组,并在组下给我们建立了一个专门用作翻译的仓库。她还把我们加入了文档作者的slack小组,让我们可以与Angular开发组亲密接触,及时了解文档的写作及更改计划。这帮助我们避免了很多无用功,并能直接跟作者讨论对原文理解不透的地方,确保译文准确无误。反过来,我们也通过这个渠道,对多处原文提出了修改意见。

To ensure that developers in China would have consistent access from a locally-hosted official domain, Google China's Developer Relations team helped us to secure angular.cn and we launched the site. When we made our work known to our Chinese community, more than 10% subscribers instantly “liked” the news in Ralph’s personal WeChat channel. Many volunteers started to provide valuable feedback on our work, many of whom preferred to be kept anonymous.  All they wanted was the feeling of being able to contribute to the community. Our work has also attracted many new Angular developers to the the community.
为了帮助在中国的开发者们能够从基于国内的服务器方便地得到统一和一致性的资源使用,谷歌开发技术推广部的中国团队帮助我们获得了angular.cn的域名并发布了这个网站。当我们向社区通告了我们的工作成果,10%以上的成员们马上在汪志成的微信朋友圈中点了赞。很多志愿者开始向我们的工作提供回馈,他们中的很多人甚至都不愿意署名,他们所追求的只是为社区贡献力量的感觉而已。我们的工作还吸引了很多原本在Angular开发者社区之外的开发者们来加入我们这个社区。

Although we expected a positive response from the community according to our past experience with Angular 1, we were still surprised with the overwhelming praises and positive feedback received. Bear in mind that some developers were skeptical about Angular 2’s brand new design approach initially. It looks like Angular 2 has eventually won their heart.
虽然早就从Angular 1的经验中就对社区的正面反响有所期待,但是这个新的网站的发布以及获得的反应仍然超出了我们的想象。要知道,有些人对Angular 2的全新设计曾经是持怀疑态度的。看来,Angular 2的这些优异特性还是赢得了他们的心。

Our work has received great acceptance and recognition in the community. It has helped many developer teams overcome the language barriers. Many teams have started or are preparing to adopt Angular 2 in their projects. There are also a huge amount of developers starting to learn and play with angular 2 in their open source projects.  The Chinese Angular community has become more active than ever since the launch of angular.cn. More and more developers have become involved in the community by actively exchanging ideas and helping solve other people’s issues.
我们的努力和工作成果获得了开发者社区的接受和认可,它帮助了中国的开发者们克服了语言的障碍。已经有不少项目团队开始在筹备或使用Angular 2开发他们的项目,也有大批的开发者们在开始学习或尝试在他们的开源代码项目中使用Angular 2。自从Angular.cn网站发布之后,中国的Angular开发者社区变得更加活跃,越来越多的开发者们参与到我们的社区中来积极进行分享、交流、以及互相帮助解决开发问题。

We have also organised a team of Angular experts to translate the new ng-book 2. We will retain the same quality standard and we aim to publish the book shortly after the official release of Angular 2. We hope this will help Angular 2 take off to a flying start in China!
我们还组织了一个Angular专家团队来准备翻译并出版ng-book2。我们将坚持同样的质量标准和高效率,争取能在官方发布后不久就让本书面世,为Angular中文社区来一个开门红。

The workload for the localisation is not the lightest, however it has given us great sense of accomplishment and helped us build influence in our community. If you want to contribute and at the same time obtain recognition from the community, this is the opportunity you do not want to miss. If your local community is not yet strong, this could be the starting point to build a better and stronger one. Would you like to try replicating this effort for your language? The Angular team is looking for leads to bootstrap similar projects in other countries, and we would love to help you.
虽然翻译的工作确实相当繁重,但其成就感和影响力也同样非凡。如果你想付出努力并取得所属社区的认可,这将是一个难得的机会。如果你的社区尚且孱弱,这也是一个建设并发展它的绝好时机。你愿意为Angular技术文档的翻译工作提供你的贡献吗?  Angular产品部门正在寻找更多的志愿者们来做为其它国家市场类似的翻译工作,我们很期盼有更多的志愿者们来加入我们。

There is only one Angular community and that is the global Angular community. Let us work to build up our local communities and connect them together through the Angular team, to form an ever growing Angular community worldwide.
本质上,Angular只有一个社区,那就是全球社区。让我们大家一起努力和协作,建设好我们中国的Angular社区,并通过谷歌Angular产品部门的纽带,让它成为全球不断发展壮大的Angular社区的一部分。

One flower does not bring the spring, one tree does not make a forest. Only a prosperous community could make a technology succeed. The work we have done has not only brought us a great sense of achievement, more importantly it has helped form the building blocks of a stronger community. In this day and age, only a strong community can prevent a technology from becoming obsolete quickly. Only a strong community can help us get support from each other whenever we need. Only a strong community can feed the ever growing job market, which is crucial for business success. More importantly, in the process of building up our community, we will meet countless good friends - maybe, we are already friends, we are just waiting to discover each other.
一花不成春,独木不成林。只有繁荣的社区才能让一项技术发扬光大。我们所做的这些工作,除了给个人带来荣誉之外,更重要的是它有助于建设并保持一个强大的社区。只有强大的社区,才能让我们之所学不至于成为夕阳技术;每个人都有思维盲点,只有强大的社区,才能让我们在将来遇到问题时,可以向他人求助;而将来当我们无论是以技术骨干的身份还是以创业者的身份求贤若渴时,也只有强大的社区才能为我们提供源源不断的高质量的小伙伴儿。最重要的是,在建设社区的过程中,我们结识了很多原本陌生的朋友 —— 或许,他们原本就是我们的朋友,只是在世界的某个角落等待我们去发现而已。

Contributing to a strong community is the best way to pay back to the Angular team for their continuous investment in Angular.
贡献与一个强大的社区,也是我们对Angular产品部门做作的不断的投资所能给与的最佳回报。

If we can do it, you can!
我行,你也行!

Dear friends, we look forward to joining forces with you soon!
期待有一天能与你们胜利会师。

Ralph Wang and Rex Ye
汪志成 & 叶志敏