Showing posts with label 2.0. Show all posts
Showing posts with label 2.0. Show all posts

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.

Wednesday, September 14, 2016

Angular, version 2: proprioception-reinforcement

Today, at a special meetup at Google HQ, we announced the final release version of Angular 2, the full-platform successor to Angular 1.

What does "final" mean? Stability that's been validated across a wide range of use cases, and a framework that's been optimized for developer productivity, small payload size, and performance. With ahead-of-time compilation and built-in lazy-loading, we’ve made sure that you can deploy the fastest, smallest applications across the browser, desktop, and mobile environments. This release also represents huge improvements to developer productivity with the Angular CLI and styleguide.
Angular 1 first solved the problem of how to develop for an emerging web. Six years later, the challenges faced by today’s application developers, and the sophistication of the devices that applications must support, have both changed immensely. With this release, and its more capable versions of the Router, Forms, and other core APIs, today you can build amazing apps for any platform. If you prefer your own approach, Angular is also modular and flexible, so you can use your favorite third-party library or write your own.
From the beginning, we built Angular in collaboration with the open source development community. We are grateful to the large number of contributors who dedicated time to submitting pull requests, issues, and repro cases, who discussed and debated design decisions, and validated (and pushed back on) our RCs. We wish we could have brought every one of you in person to our meetup so you could celebrate this milestone with us tonight!
Angular Homepage.png

What’s next?

Angular is now ready for the world, and we’re excited for you to join the thousands of developers already building with Angular 2.  But what’s coming next for Angular?


A few of the things you can expect in the near future from the Angular team:


  • Bug fixes and non-breaking features for APIs marked as stable
  • More guides and live examples specific to your use cases
  • More work on animations
  • Angular Material 2
  • Moving WebWorkers out of experimental
  • More features and more languages for Angular Universal
  • Even more speed and payload size improvements


Semantic Versioning

We heard loud and clear that our RC labeling was confusing. To make it easy to manage dependencies on stable Angular releases, starting today with Angular 2.0.0, we will move to semantic versioning.  Angular versioning will then follow the MAJOR.MINOR.PATCH scheme as described by semver:


  1. the MAJOR version gets incremented when incompatible API changes are made to stable APIs,
  2. the MINOR version gets incremented when backwards-compatible functionality are added,
  3. the PATCH version gets incremented when backwards-compatible bug are fixed.


Moving Angular to semantic versioning ensures rapid access to the newest features for our component and tooling ecosystem, while preserving a consistent and reliable development environment for production applications that depend on stability between major releases, but still benefit from bug fixes and new APIs.

Contributors

Aaron Frost, Aaron (Ron) Tsui, Adam Bradley, Adil Mourahi, agpreynolds, Ajay Ambre, Alberto Santini, Alec Wiseman, Alejandro Caravaca Puchades, Alex Castillo, Alex Eagle, Alex Rickabaugh, Alex Wolfe, Alexander Bachmann, Alfonso Presa, Ali Johnson, Aliaksei Palkanau, Almero Steyn, Alyssa Nicoll, Alxandr, André Gil, Andreas Argelius, Andreas Wissel, Andrei Alecu, Andrei Tserakhau, Andrew, Andrii Nechytailov, Ansel Rosenberg, Anthony Zotti, Anton Moiseev, Artur Meyster, asukaleido, Aysegul Yonet, Aziz Abbas, Basarat Ali Syed, BeastCode, Ben Nadel, Bertrand Laporte, Blake La Pierre, Bo Guo, Bob Nystrom, Borys Semerenko, Bradley Heinz, Brandon Roberts, Brendan Wyse, Brian Clark, Brian Ford, Brian Hsu, dozingcat, Brian Yarger, Bryce Johnson, CJ Avilla, cjc343, Caitlin Potter, Cédric Exbrayat, Chirayu Krishnappa, Christian Weyer, Christoph Burgdorf, Christoph Guttandin, Christoph Hoeller, Christoffer Noring, Chuck Jazdzewski, Cindy, Ciro Nunes, Codebacca, Cody Lundquist, Cody-Nicholson, Cole R Lawrence, Constantin Gavrilete, Cory Bateman, Craig Doremus, crisbeto, Cuel, Cyril Balit, Cyrille Tuzi, Damien Cassan, Dan Grove, Dan Wahlin, Daniel Leib, Daniel Rasmuson, dapperAuteur, Daria Jung, David East, David Fuka, David Reher, David-Emmanuel Divernois, Davy Engone, Deborah Kurata, Derek Van Dyke, DevVersion, Dima Kuzmich, Dimitrios Loukadakis, Dmitriy Shekhovtsov, Dmitry Patsura, Dmitry Zamula, Dmytro Kulyk, Donald Spencer, Douglas Duteil, dozingcat, Drew Moore, Dylan Johnson, Edd Hannay, Edouard Coissy, eggers, elimach, Elliott Davis, Eric Jimenez, Eric Lee Carraway, Eric Martinez, Eric Mendes Dantas, Eric Tsang, Essam Al Joubori, Evan Martin, Fabian Raetz, Fahimnur Alam, Fatima Remtullah, Federico Caselli, Felipe Batista, Felix Itzenplitz, Felix Yan, Filip Bruun, Filipe Silva, Flavio Corpa, Florian Knop, Foxandxss, Gabe Johnson, Gabe Scholz, GabrielBico, Gautam krishna.R, Georgii Dolzhykov, Georgios Kalpakas, Gerd Jungbluth, Gerard Sans, Gion Kunz, Gonzalo Ruiz de Villa, Grégory Bataille, Günter Zöchbauer, Hank Duan, Hannah Howard, Hans Larsen, Harry Terkelsen, Harry Wolff, Henrique Limas, Henry Wong, Hiroto Fukui, Hongbo Miao, Huston Hedinger, Ian Riley, Idir Ouhab Meskine, Igor Minar, Ioannis Pinakoulakis, The Ionic Team, Isaac Park, Istvan Novak, Itay Radotzki, Ivan Gabriele, Ivey Padgett, Ivo Gabe de Wolff, J. Andrew Brassington, Jack Franklin, Jacob Eggers, Jacob MacDonald, Jacob Richman, Jake Garelick, James Blacklock, James Ward, Jason Choi, Jason Kurian, Jason Teplitz, Javier Ros, Jay Kan, Jay Phelps, Jay Traband, Jeff Cross, Jeff Whelpley, Jennifer Bland, jennyraj, Jeremy Attali, Jeremy Elbourn, Jeremy Wilken, Jerome Velociter, Jesper Rønn-Jensen, Jesse Palmer, Jesús Rodríguez, Jesús Rodríguez, Jimmy Gong, Joe Eames, Joel Brewer, John Arstingstall, John Jelinek IV, John Lindquist, John Papa, John-David Dalton, Jonathan Miles, Joost de Vries, Jorge Cruz, Josef Meier, Josh Brown, Josh Gerdes, Josh Kurz, Josh Olson, Josh Thomas, Joseph Perrott, Joshua Otis, Josu Guiterrez, Julian Motz, Julie Ralph, Jules Kremer, Justin DuJardin, Kai Ruhnau, Kapunahele Wong, Kara Erickson, Kathy Walrath, Keerti Parthasarathy, Kenneth Hahn, Kevin Huang, Kevin Kirsche, Kevin Merckx, Kevin Moore, Kevin Western, Konstantin Shcheglov, Kurt Hong, Levente Morva, laiso, Lina Lu, LongYinan, Lucas Mirelmann, Luka Pejovic, Lukas Ruebbelke, Marc Fisher, Marc Laval, Marcel Good, Marcy Sutton, Marcus Krahl, Marek Buko, Mark Ethan Trostler, Martin Gontovnikas, Martin Probst, Martin Staffa, Matan Lurey, Mathias Raacke, Matias Niemelä, Matt Follett, Matt Greenland, Matt Wheatley, Matteo Suppo, Matthew Hill, Matthew Schranz, Matthew Windwer, Max Sills, Maxim Salnikov, Melinda Sarnicki Bernardo, Michael Giambalvo, Michael Goderbauer, Michael Mrowetz, Michael-Rainabba Richardson, Michał Gołębiowski, Mikael Morlund, Mike Ryan, Minko Gechev, Miško Hevery, Mohamed Hegazy, Nan Schweiger, Naomi Black, Nathan Walker, The NativeScript Team, Nicholas Hydock, Nick Mann, Nick Raphael, Nick Van Dyck, Ning Xia, Olivier Chafik, Olivier Combe, Oto Dočkal, Pablo Villoslada Puigcerber, Pascal Precht, Patrice Chalin, Patrick Stapleton, Paul Gschwendtner, Pawel Kozlowski, Pengfei Yang, Pete Bacon Darwin, Pete Boere, Pete Mertz, Philip Harrison, Phillip Alexander, Phong Huynh, Polvista, Pouja, Pouria Alimirzaei, Prakal, Prayag Verma, Rado Kirov, Raul Jimenez, Razvan Moraru, Rene Weber, Rex Ye, Richard Harrington, Richard Kho, Richard Sentino, Rob Eisenberg, Rob Richardson, Rob Wormald, Robert Ferentz, Robert Messerle, Roberto Simonetti, Rodolfo Yabut, Sam Herrmann, Sam Julien, Sam Lin, Sam Rawlins, Sammy Jelin, Sander Elias, Scott Hatcher, Scott Hyndman, Scott Little, ScottSWu, Sebastian Hillig, Sebastian Müller, Sebastián Duque, Sekib Omazic, Shahar Talmi, Shai Reznik, Sharon DiOrio, Shannon Ayres, Shefali Sinha, Shlomi Assaf, Shuhei Kagawa, Sigmund Cherem, Simon Hürlimann (CyT), Simon Ramsay, Stacy Gay, Stephen Adams, Stephen Fluin, Steve Mao, Steve Schmitt, Suguru Inatomi, Tamas Csaba, Ted Sander, Tero Parviainen, Thierry Chatel, Thierry Templier, Thomas Burleson, Thomas Henley, Tim Blasi, Tim Ruffles, Timur Meyster, Tobias Bosch, Tony Childs, Tom Ingebretsen, Tom Schoener, Tommy Odom, Torgeir Helgevold, Travis Kaufman, Trotyl Yu, Tycho Grouwstra, The Typescript Team, Uli Köhler, Uri Shaked, Utsav Shah, Valter Júnior, Vamsi V, Vamsi Varikuti, Vanga Sasidhar, Veikko Karsikko, Victor Berchet, Victor Mejia, Victor Savkin, Vinci Rufus, Vijay Menon, Vikram Subramanian, Vivek Ghaisas, Vladislav Zarakovsky, Vojta Jina, Ward Bell, Wassim Chegham, Wenqian Guo, Wesley Cho, Will Ngo, William Johnson, William Welling, Wilson Mendes Neto, Wojciech Kwiatek, Yang Lin, Yegor Jbanov, Zach Bjornson, Zhicheng Wang, and many more...


With gratitude and appreciation, and anticipation to see what you'll build next, welcome to the next stage of Angular.

Thursday, September 1, 2016

Angular 2 RC6


Angular 2.0.0-rc.6 is now available on npm! New in this release candidate:

The API surface is now final for all stable API symbols. This also means that previously deprecated APIs are removed in RC6.

For full details, see the CHANGELOG.md.

Faster Angular 2

Ahead of Time (AoT) Compilation

We’re really excited about the speed and bundle size improvements developers get when compiling applications ahead of time.  To take advantage of AoT compilation, you’ll need to install the @angular/compiler-cli and make a small addition to your tsconfig.json file.

  "angularCompilerOptions": {
    "genDir": "./ngfactory"
  }

Once you make this change, you can run the Angular compiler from the command-line, by typing ngc.

Then update your bootstrap from
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
platformBrowserDynamic().bootstrapModule(MyAppModule)
to
import {platformBrowser} from '@angular/platform-browser';
platformBrowser().bootstrapModuleFactory(MyAppModuleNgFactory)

These two changes will get you started with using ngc and AoT, but we have more documentation and tools coming. Developers looking to try AoT may run into errors the first time they try - don’t panic! One of the benefits of the introduction of NgModules is that your code does not have to change based on whether you’re running in AoT or just in time (JiT) mode, so you can continue to be productive while we continue to improve these tools and work with third-party library authors to make sure code is AoT compilable.

ES2015 modules

In RC6, we’ve changed the output structure of our NPM packages to better enable tools like Rollup and Webpack2 to optimize your applications during bundling.

Each @angular/* package now contains:
  • “ESM” code - this is ES5 code with ES2015 style import/exports. This works great with Rollup and Webpack2 and allows more efficient tree shaking. This code replaces the commonJS source in the root of each directory.
  • A UMD bundle in the bundles/ directory of each package.
  • A new field in the package.json - “module” - that allows Rollup and Webpack to opt into using the ESM code.
For most users, this should work with no changes - but in case of any issues, here’s a list of config setups for various tooling: https://gist.github.com/robwormald/29f3dcda1a06b955d83fccb2a94586eb

If you’ve previously deep imported from @angular packages (e.g. @angular/core/src/foo/bar), note that this no longer works in RC6. Always import from the root of a package (eg, @angular/core). Deep imports are private APIs, and likely to change.

Wednesday, July 20, 2016

A dedicated team for AngularDart

Until now, the multiple language flavors of Angular 2 were written as TypeScript source, and then automatically compiled to both JavaScript and Dart.  We're happy to announce that going forward, we are splitting the Angular 2 codebase into two flavors—a Dart version and a TypeScript/JavaScript version—and creating a dedicated Angular Dart team.

While this single-source multi-language approach worked in theory, in practice it made it much harder for new contributors to add to the project. Even simple changes could quickly become complicated by cross-language compatibility concerns, and many changes could only be made by someone who understood the entire compilation process and both language targets.

For developers, this doesn't really change much about how you use our APIs, except that it will become easier to contribute changes, and we'll be able to fix issues faster. Both versions will share the same template syntax and, where appropriate, the same API. But you'll have the freedom to submit pull requests in the language that you know best, and changes can be made and reviewed without the added burdens of compilation and cross-compatibility to downstream languages.

For Dart developers, the Angular Dart source code will become cleaner and more Dart-y.  With a dedicated team of Dart experts, we'll be able to close issues more quickly, and finally update all of the documentation with a Dart focus. You'll also be able to use many Dart-specific features that weren't compatible with the TypeScript flavor. And it will be faster. Read more on news.dartlang.org.

If you're a TypeScript or JavaScript developer, you'll also benefit from cleaner JavaScript APIs and performance gains as we simplify the TypeScript codebase to remove the need for compilation to Dart.

We're all excited about this change, and we believe it'll make Angular 2 more useful for everyone involved.

— the Angular team & the Dart team

Thursday, June 30, 2016

RC4 Now Available

Today we’re happy to announce that we are shipping Angular 2.0.0-rc.4. This release includes many bugfixes and improvements, and makes testing easier and more flexible.

What's new?

  • We've cleaned up our exported APIs so that they are simpler and more streamlined, and removed things that were never intended to be public. We have also added stability tag filtering so that you can easily tell whether something is part of the stable released API or experimental.
  • Consolidation and improvements to testing. For example, we no longer do special wrapping around Jasmine's it, describe, or other functions. This means we are no longer coupled to Jasmine, you can use another testing framework such as Mocha.
  • We've added more Resources to help you learn and use Angular.
Read the full release notes

Tuesday, June 21, 2016

RC3 Now Available

Today we’re happy to announce that we are shipping Angular 2.0.0-rc3.

What's new?

  • This release includes a fix for a major performance regression in RC2
  • The @angular/router project has been merged into our main repository ( It will retain its own version numbers and release cycle )
  • The Router documentation is now available. 
  • Content Security - Angular Content Security features are feature-complete and documented
  • The new Forms cookbook is available
Read the full release notes