diff --git a/SafeCity/ClientApp/src/index.tsx b/SafeCity/ClientApp/src/index.tsx
index d56bac5..fbf20ae 100644
--- a/SafeCity/ClientApp/src/index.tsx
+++ b/SafeCity/ClientApp/src/index.tsx
@@ -3,8 +3,15 @@ import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import './index.css';
import App from './App';
+import auth from './services/auth';
import * as serviceWorker from './serviceWorker';
+auth.load(updateSigninStatus);
+
+function updateSigninStatus(isSignedIn: boolean) {
+ console.log(`app loaded, signed in: ${isSignedIn} token: ${auth.getToken()}`);
+}
+
const rootElement = document.getElementById('root');
ReactDOM.render(
diff --git a/SafeCity/ClientApp/src/pages/Layout.tsx b/SafeCity/ClientApp/src/pages/Layout.tsx
index 36a3761..0a40d20 100644
--- a/SafeCity/ClientApp/src/pages/Layout.tsx
+++ b/SafeCity/ClientApp/src/pages/Layout.tsx
@@ -2,6 +2,7 @@ import React from 'react';
import { NavLink } from 'react-router-dom';
import Navbar from 'react-bootstrap/Navbar';
import Nav from 'react-bootstrap/Nav';
+import auth from '../services/auth';
function Layout(props: any) {
return (
@@ -24,6 +25,9 @@ function Layout(props: any) {
Про нас
+
+
+
diff --git a/SafeCity/ClientApp/src/services/auth.ts b/SafeCity/ClientApp/src/services/auth.ts
new file mode 100644
index 0000000..ada7b88
--- /dev/null
+++ b/SafeCity/ClientApp/src/services/auth.ts
@@ -0,0 +1,49 @@
+const CLIENT_ID = '674253053711-5kesmhgnisu9hukdgf7l6v8k9scs85s8.apps.googleusercontent.com';
+
+declare global {
+ interface Window {
+ gapi: any;
+ }
+}
+
+function loadScript(callback: any) {
+ const script = document.createElement('script');
+
+ script.src = `https://apis.google.com/js/api.js`;
+ script.async = true;
+
+ document.head.appendChild(script);
+ script.onload = callback
+};
+
+function getToken() {
+ return window.gapi ? window.gapi.auth2.getAuthInstance().currentUser.get().getAuthResponse().id_token : undefined;
+};
+
+function signIn() {
+ window.gapi.auth2.getAuthInstance().signIn()
+ .then(() => console.log('signed in'));
+};
+
+function signOut() {
+ window.gapi.auth2.getAuthInstance().signOut()
+ .then(() => console.log('User signed out.'));
+};
+
+export default {
+ load: (updateSigninStatus: Function) => loadScript(() => {
+ window.gapi.load('auth2', () => {
+ window.gapi.auth2.init({
+ clientId: CLIENT_ID,
+ }).then(() => {
+ window.gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus);
+ updateSigninStatus(window.gapi.auth2.getAuthInstance().isSignedIn.get());
+ }, (error: any) => {
+ console.log('failed to initialize google API client ', error);
+ });
+ });
+ }),
+ getToken: getToken,
+ signIn:signIn,
+ signOut:signOut,
+}
\ No newline at end of file
diff --git a/SafeCity/ClientApp/src/services/crud.ts b/SafeCity/ClientApp/src/services/crud.ts
index 94c3845..7e349a6 100644
--- a/SafeCity/ClientApp/src/services/crud.ts
+++ b/SafeCity/ClientApp/src/services/crud.ts
@@ -1,12 +1,15 @@
+import auth from './auth';
-export async function get(url:string) {
- const idToken = 'dummy_token';
- const options = {
- method: 'GET',
- headers: {
- 'Authorization': `Bearer ${idToken}`,
- },
- };
+enum Method {
+ GET = 'GET',
+ POST = 'POST',
+ PUT = 'PUT',
+ DELETE = 'DELETE',
+}
+
+export async function get(url: string) {
+ const options = getOptions(Method.GET);
+
return new Promise((resolve, reject) => {
fetch(url, options)
.then(res => {
@@ -24,21 +27,16 @@ export async function get(url:string) {
};
export async function post(url:string, entity:any) {
- return await action(url, 'POST', entity);
+ return await action(url, Method.POST, entity);
};
export async function put(url:string, entity:any) {
- return await action(url, 'PUT', entity);
+ return await action(url, Method.PUT, entity);
};
export async function del(url:string) {
- const idToken = 'dummy_token';
- const options = {
- headers: {
- 'Authorization': `Bearer ${idToken}`,
- },
- method: 'DELETE',
- };
+ const options = getOptions(Method.DELETE);
+
return new Promise((resolve, reject) => {
fetch(url, options)
.then(res => {
@@ -51,17 +49,29 @@ export async function del(url:string) {
});
};
-async function action(url:string, method:string, entity:any) {
- const idToken = 'dummy_token';
+function getOptions(method:Method, entity:any|undefined = undefined): RequestInit{
+ const idToken = auth.getToken();
+
const options = {
- method: method,
- headers: {
+ method,
+ } as RequestInit;
+
+ if(idToken){
+ options.headers = {
'Authorization': `Bearer ${idToken}`,
'Accept': 'application/json',
'Content-Type': 'application/json'
- },
- body: JSON.stringify(entity),
- };
+ };
+ }
+ if(entity){
+ options.body = JSON.stringify(entity);
+ }
+
+ return options;
+};
+
+async function action(url:string, method:Method, entity:any) {
+ const options = getOptions(method, entity);
return new Promise((resolve, reject) => {
fetch(url, options)
diff --git a/SafeCity/Controllers/ProjectsController.cs b/SafeCity/Controllers/ProjectsController.cs
index dca53e4..8ec384c 100644
--- a/SafeCity/Controllers/ProjectsController.cs
+++ b/SafeCity/Controllers/ProjectsController.cs
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
-using System.Linq;
using System.Threading.Tasks;
using AutoMapper;
using SafeCity.DTOs;
diff --git a/SafeCity/SafeCity.csproj b/SafeCity/SafeCity.csproj
index 443f35a..7dd1ea1 100644
--- a/SafeCity/SafeCity.csproj
+++ b/SafeCity/SafeCity.csproj
@@ -11,6 +11,8 @@
+
+
diff --git a/SafeCity/Startup.cs b/SafeCity/Startup.cs
index 537a32c..f06968e 100644
--- a/SafeCity/Startup.cs
+++ b/SafeCity/Startup.cs
@@ -1,7 +1,7 @@
using AutoMapper;
+using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
-using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.SpaServices.ReactDevelopmentServer;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
@@ -25,23 +25,12 @@ public Startup(IConfiguration configuration)
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
- services.AddMvc(p =>
- {
- p.EnableEndpointRouting = false;
- });
+ services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
+ .AddJwtBearer(jwt => jwt.UseGoogle(
+ clientId: Configuration["Authentication:Google:ClientId"]));
- services.AddControllersWithViews();
services.AddControllers().AddNewtonsoftJson();
- services.AddDbContext(
- opt => opt.UseNpgsql(Configuration["ConnectionStrings:SafeCityConnectionString"]));
-
- // In production, the React files will be served from this directory
- services.AddSpaStaticFiles(configuration =>
- {
- configuration.RootPath = "ClientApp/build";
- });
-
services.AddHttpContextAccessor();
services.AddScoped();
@@ -51,6 +40,20 @@ public void ConfigureServices(IServiceCollection services)
new LiqPayService(Configuration["LiqPay:PublicKey"], Configuration["LiqPay:PrivateKey"]));
services.AddAutoMapper(typeof(Startup).Assembly);
+
+ services.AddMvc(p =>
+ {
+ p.EnableEndpointRouting = false;
+ });
+
+ services.AddDbContext(
+ opt => opt.UseNpgsql(Configuration["ConnectionStrings:SafeCityConnectionString"]));
+
+ // In production, the React files will be served from this directory
+ services.AddSpaStaticFiles(configuration =>
+ {
+ configuration.RootPath = "ClientApp/build";
+ });
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
@@ -67,20 +70,16 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
app.UseHsts();
}
- app.UseMvc();
-
+ //app.UseMvc();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseSpaStaticFiles();
- app.UseRouting();
+ //app.UseRouting();
- app.UseEndpoints(endpoints =>
- {
- endpoints.MapControllerRoute(
- name: "default",
- pattern: "{controller}/{action=Index}/{id?}");
- });
+ app.UseAuthentication();
+
+ app.UseMvcWithDefaultRoute();
app.UseSpa(spa =>
{
diff --git a/SafeCity/appsettings.Development.json b/SafeCity/appsettings.Development.json
index 126a2e5..8b268e6 100644
--- a/SafeCity/appsettings.Development.json
+++ b/SafeCity/appsettings.Development.json
@@ -12,5 +12,10 @@
"LiqPay": {
"PublicKey": "sandbox_i98303515576",
"PrivateKey": "sandbox_fXB33L5nU5kWoNJC1bh26Z3h3ZVU2flGfci3hhDs"
- }
+ },
+ "Authentication": {
+ "Google": {
+ "ClientId": "674253053711-5kesmhgnisu9hukdgf7l6v8k9scs85s8.apps.googleusercontent.com"
+ }
+ }
}
\ No newline at end of file