Skip to content

Instantly share code, notes, and snippets.

@ZhenDeng
Last active April 9, 2019 07:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ZhenDeng/339bbe46490f4093ee73bfa7dc16876a to your computer and use it in GitHub Desktop.
Save ZhenDeng/339bbe46490f4093ee73bfa7dc16876a to your computer and use it in GitHub Desktop.
1. Go to appsettings.json file and add the secret key for the JWT encryption.
"AppSettings": {
"Secret": "HHPM0JEOMLGYXYU5YS32"
},
2. Create a class as “AppSettings.cs” to access the AppSetting values trough a class.
namespace NetCoreWebAPI.Helpers
{
public class AppSettings
{
public string Secret { get; set; }
}
}
3. Add the following code to Startup.cs class to configure the request pipeline to handle all requests.
No need to add additional assemblies. All the relevant assemblies will be at .Net core project by default.
namespace NetCoreWebAPI
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
// JWT related code
services.AddCors();
// Configure asettings.jason values to an objects
var appSettingsSection = Configuration.GetSection("AppSettings");
services.Configure<AppSettings>(appSettingsSection);
// Configure JWT authentication
var appSettings = appSettingsSection.Get<AppSettings>();
var key = Encoding.ASCII.GetBytes(appSettings.Secret);
services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(x =>
{
x.RequireHttpsMetadata = false;
x.SaveToken = true;
x.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false
};
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
// JWT related code
app.UseCors(x => x
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
app.UseAuthentication();
app.UseMvc();
}
}
}
4. Create a Model class as UserModel
namespace NetCoreWebAPI.Models
{
public class UserModel
{
public string Username { get; set; }
public string Password { get; set; }
}
}
5. Add new API Controller as “UserController”
namespace NetCoreWebAPI.Controllers
{
[Produces("application/json")]
[Route("api/User")]
public class UserController : Controller
{
private readonly AppSettings _appSettings;
public UserController(IOptions<AppSettings> appSettings)
{
_appSettings = appSettings.Value;
}
[AllowAnonymous]
[HttpPost("authenticate")]
public IActionResult Authenticate([FromBody]UserModel userModel)
{
if(ModelState.IsValid)
{
if(userModel.Username != "admin" || userModel.Password != "123")
{
return Unauthorized();
}
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.ASCII.GetBytes(_appSettings.Secret);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new Claim[]
{
new Claim(ClaimTypes.Name, userModel.Username)
}),
Expires = DateTime.UtcNow.AddMinutes(20),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
var tokenString = tokenHandler.WriteToken(token);
// return basic user info and token to store client side
return Ok(new
{
Username = userModel.Username,
Token = tokenString
});
}
else
{
return Unauthorized();
}
}
}
}
6. add a test controller
[Route("api/[Controller]")]
[Authorize]
public class CompanyInfoController: Controller
{
[HttpGet]
public IActionResult Get()
{
return Ok("test");
}
}
1. in app.route.ts
const appRoutes: Routes = [
{ path: 'home', component: HomeComponent, canActivate: [AuthGuard] },
{ path: 'account', component: AccountDetailsComponent, canActivate: [AuthGuard] },
{
path: 'login', component: LoginComponent
},
{
path: '',
redirectTo: '/home',
pathMatch: 'full'
}
];
export const RoutingModule: ModuleWithProviders = RouterModule.forRoot(appRoutes);
2. in app.module.ts
@NgModule({
declarations: [
AppComponent,
HomeComponent,
LoginComponent
],
imports: [
BrowserModule.withServerTransition({ appId: 'ng-cli-universal' }),
HttpClientModule,
FormsModule,
RoutingModule,
BrowserAnimationsModule,
MatFormFieldModule,
ReactiveFormsModule,
MatInputModule
],
providers: [
UserService,
AuthGuard,
{
provide: HTTP_INTERCEPTORS,
useClass: AuthInterceptor,
multi: true
}],
bootstrap: [AppComponent]
})
export class AppModule { }
3. in user.service.ts
@Injectable()
export class UserService {
selectedUser: User;
base_url: string = "api/User";
constructor(private http: HttpClient) { }
userAuthentication(user: any): Observable<UserResponse> {
console.info(user);
return this.http.post(this.base_url + "/authenticate", user, {headers: new HttpHeaders({'Content-Type':'application/json', 'No-Auth': 'True'})})
.pipe(catchError(this.handleError));
}
private handleError(error: HttpErrorResponse) {
console.error('server error:', error);
if (error.error instanceof ErrorEvent) {
let errMessage = '';
try {
errMessage = error.error.message;
} catch (err) {
errMessage = error.statusText;
}
return Observable.throw(errMessage);
}
return Observable.throw(error.error || 'ASP.NET Core server error');
}
}
4. in auth.guard.ts
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private router: Router){}
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): boolean {
if(localStorage.getItem('userToken') != null) {
return true;
}
else{
this.router.navigate(['/login']);
return false;
}
}
}
5. in auth.interceptor.ts
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
constructor(private router: Router) {}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if(request.headers.get('No-Auth') == "True"){
return next.handle(request.clone());
}
if(localStorage.getItem('userToken') != null) {
return next.handle(
request.clone(
{ headers: request.headers.set("Authorization", "Bearer " + localStorage.getItem('userToken'))}
)
);
}
else{
this.router.navigateByUrl('/login');
}
}
}
6. in login component
<div class="login-box" [formGroup]="userFormGroup">
<p>MEMBER LOGIN</p>
<mat-form-field [floatLabel]="'always'" class="col-md-12">
<input matInput formControlName="account" placeholder="USERNAME">
</mat-form-field>
<mat-form-field [floatLabel]="'always'" class="col-md-12">
<input matInput formControlName="password" placeholder="PASSWORD">
</mat-form-field>
<button class="btn btn-long" (click)="onSubmit()">LOGIN IN</button>
<button class="btn btn-long">FORGETTEN PASSWORD?</button>
</div>
export class LoginComponent implements OnInit {
userFormGroup: FormGroup;
constructor(
private userService: UserService,
private router: Router,
private formBuilder: FormBuilder) {
this.userFormGroup = this.formBuilder.group({
account: new FormControl("", Validators.compose([Validators.required])),
password: new FormControl("", Validators.compose([Validators.required]))
});
}
ngOnInit() {
}
onSubmit() {
this.userService.userAuthentication(this.userFormGroup.value).subscribe((data: UserResponse) => {
console.info(data);
localStorage.setItem('userToken', data.token);
this.router.navigate(['/home'])
},
(error: any) => {
console.info(error);
});
}
}
7. can get data from test controller with [Authorize]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment