Alıştırma - Kullanıcı kimlik doğrulaması ekleme
Alışveriş listesi web uygulamanızın kullanıcı kimlik doğrulamasına ihtiyacı var. Bu alıştırmada, uygulamanızda oturum açma ve oturumu kapatma uygulayacak ve geçerli kullanıcı oturum açma durumunu görüntüleyeceksiniz.
Bu alıştırmada aşağıdaki adımları tamamlayacaksınız:
- Yerel geliştirme için Static Web Apps CLI'sini yükleyin.
- Uygulamayı ve API'yi yerel kimlik doğrulama öykünmesi ile yerel olarak çalıştırın.
- Birden çok kimlik doğrulama sağlayıcısı için oturum açma düğmeleri ekleyin.
- Kullanıcı oturum açtıysa bir oturum kapatma düğmesi ekleyin.
- Kullanıcının oturum açma durumunu görüntüleyin.
- Kimlik doğrulama iş akışını yerel olarak test edin.
- Güncelleştirilmiş uygulamayı dağıtın.
Yerel geliştirme için hazırlanma
SWA CLI olarak da bilinen Static Web Apps CLI, web uygulamanızı ve API'nizi yerel olarak çalıştırmanıza ve kimlik doğrulaması ile yetkilendirme sunucularına öykünmenize olanak tanıyan yerel bir geliştirme aracıdır.
Bilgisayarınızda bir terminali açın.
Aşağıdaki komutu çalıştırarak SWA CLI'yi yükleyin.
npm install -g @azure/static-web-apps-cli
Uygulamayı yerel olarak çalıştırma
Şimdi uygulamayı ve API'yi bir geliştirme sunucusuyla yerel olarak çalıştırın. Bu şekilde, değişikliklerinizi kodda yaptığınız gibi görebilir ve test edebilirsiniz.
Projeyi Visual Studio Code'da açın.
Visual Studio Code'da F1 tuşuna basarak komut paletini açın.
Terminal: Yeni Tümleşik Terminal Oluştur'u girin ve seçin.
Tercih ettiğiniz ön uç çerçevesinin klasörüne aşağıdaki gibi gidin:
cd angular-app
cd react-app
cd svelte-app
cd vue-app
Geliştirme sunucusu kullanarak ön uç istemci uygulamasını çalıştırın.
npm start
npm start
npm run dev
npm run serve
Bu sunucuyu arka planda çalışır durumda bırakın. Şimdi SWA CLI kullanarak API ve kimlik doğrulama sunucusu öykünücüsü çalıştırın.
Visual Studio Code'da F1 tuşuna basarak komut paletini açın.
Terminal: Yeni Tümleşik Terminal Oluştur'u girin ve seçin.
Aşağıdaki komutu çalıştırarak SWA CLI'yi çalıştırın:
swa start http://localhost:4200 --api-location ./api
swa start http://localhost:3000 --api-location ./api
swa start http://localhost:5000 --api-location ./api
swa start http://localhost:8080 --api-location ./api
http://localhost:4280
adresine göz atın.
SWA CLI tarafından kullanılan son bağlantı noktası, istekleri üç farklı bileşene iletmek için ters ara sunucu kullandığından daha önce gördüğünüzden farklıdır:
- Çerçeve geliştirme sunucunuz
- Kimlik doğrulaması ve yetkilendirme öykünücüsü
- İşlevler çalışma zamanı tarafından barındırılan API
Siz kodu değiştirirken uygulamanın çalışmaya devam etmesine izin verin.
Kullanıcı oturum açma durumunu alma
İlk olarak, istemcide bir sorgu /.auth/me
yaparak kullanıcı oturum açma durumuna erişmeniz gerekir.
Dosyayı
angular-app/src/app/core/models/user-info.ts
oluşturun ve kullanıcı bilgilerinin arabirimini temsil etmek için aşağıdaki kodu ekleyin.export interface UserInfo { identityProvider: string; userId: string; userDetails: string; userRoles: string[]; }
dosyasını
angular-app/src/app/core/components/nav.component.ts
düzenleyin ve sınıfına aşağıdaki yöntemiNavComponent
ekleyin.async getUserInfo() { try { const response = await fetch('/.auth/me'); const payload = await response.json(); const { clientPrincipal } = payload; return clientPrincipal; } catch (error) { console.error('No profile could be found'); return undefined; } }
Yeni bir sınıf özelliği
userInfo
oluşturun ve bileşen başlatıldığında zaman uyumsuz işlevingetUserInfo()
sonucunu depolayın. arabiriminiOnInit
uygulayın ve ve içeri aktarmak için içeri aktarmaOnInit
UserInfo
deyimlerini güncelleştirin. Bu kod, bileşen başlatıldığında kullanıcı bilgilerini getirir.import { Component, OnInit } from '@angular/core'; import { UserInfo } from '../model/user-info'; export class NavComponent implements OnInit { userInfo: UserInfo; async ngOnInit() { this.userInfo = await this.getUserInfo(); } // ... }
dosyasını
react-app/src/components/NavBar.js
düzenleyin ve işlevin en üstüne aşağıdaki kodu ekleyin. Bu kod, bileşen yükleyip duruma depoladığında kullanıcı bilgilerini getirir.import React, { useState, useEffect } from 'react'; import { NavLink } from 'react-router-dom'; const NavBar = (props) => { const [userInfo, setUserInfo] = useState(); useEffect(() => { (async () => { setUserInfo(await getUserInfo()); })(); }, []); async function getUserInfo() { try { const response = await fetch('/.auth/me'); const payload = await response.json(); const { clientPrincipal } = payload; return clientPrincipal; } catch (error) { console.error('No profile could be found'); return undefined; } } return ( // ...
dosyasını
svelte-app/src/components/NavBar.svelte
düzenleyin ve betik bölümüne aşağıdaki kodu ekleyin. Bu kod, bileşen yüklendiğinde kullanıcı bilgilerini getirir.import { onMount } from 'svelte'; let userInfo = undefined; onMount(async () => (userInfo = await getUserInfo())); async function getUserInfo() { try { const response = await fetch('/.auth/me'); const payload = await response.json(); const { clientPrincipal } = payload; return clientPrincipal; } catch (error) { console.error('No profile could be found'); return undefined; } }
dosyasını
vue-app/src/components/nav-bar.vue
düzenleyin ve veri nesnesine ekleyinuserInfo
.data() { return { userInfo: { type: Object, default() {}, }, }; },
getUserInfo()
yöntemini yöntemler bölümüne ekleyin.methods: { async getUserInfo() { try { const response = await fetch('/.auth/me'); const payload = await response.json(); const { clientPrincipal } = payload; return clientPrincipal; } catch (error) { console.error('No profile could be found'); return undefined; } }, },
Yaşam döngüsü kancasını
created
bileşene ekleyin.async created() { this.userInfo = await this.getUserInfo(); },
Bileşen oluşturulduğunda, kullanıcı bilgileri otomatik olarak getirilir.
Oturum açma ve oturum kapatma düğmeleri ekleme
Kullanıcı bilgileri undefined
oturum açmadıysa olacaktır, bu nedenle değişiklikler şimdilik görünür olmayacaktır. Farklı sağlayıcılar için oturum açma düğmeleri eklemenin zamanı geldi.
sınıfındaki sağlayıcıların
NavComponent
listesini eklemek için dosyasınıangular-app/src/app/core/components/nav.component.ts
düzenleyin.providers = ['x', 'github', 'aad'];
Oturum açma sonrası yeniden yönlendirmesinin geçerli URL'sini yakalamak için aşağıdaki
redirect
özelliği ekleyin.redirect = window.location.pathname;
Oturum açma ve oturum kapatma düğmelerini görüntülemek için ilk
</nav>
öğeden sonra şablona aşağıdaki kodu ekleyin.<nav class="menu auth"> <p class="menu-label">Auth</p> <div class="menu-list auth"> <ng-container *ngIf="!userInfo; else logout"> <ng-container *ngFor="let provider of providers"> <a href="/.auth/login/{{provider}}?post_login_redirect_uri={{redirect}}">{{provider}}</a> </ng-container> </ng-container> <ng-template #logout> <a href="/.auth/logout?post_logout_redirect_uri={{redirect}}">Logout</a> </ng-template> </div> </nav>
Kullanıcı oturum açmadıysa, her sağlayıcı için oturum açma düğmesini görüntülersiniz. Her düğme öğesine
/.auth/login/<AUTH_PROVIDER>
bağlanır ve yeniden yönlendirme URL'sini geçerli sayfaya ayarlar.Aksi takdirde, kullanıcı zaten oturum açmışsa, bağlantısı olan
/.auth/logout
bir oturumu kapatma düğmesi görüntülenir ve yeniden yönlendirme URL'sini geçerli sayfaya ayarlar.
Şimdi bu web sayfasını tarayıcınızda görmeniz gerekir.
İşlevin en üstüne sağlayıcı listesi eklemek için dosyayı
react-app/src/components/NavBar.js
düzenleyin.const providers = ['x', 'github', 'aad'];
Oturum açma sonrası yeniden yönlendirme için geçerli URL'yi yakalamak için ilk değişkenin altına aşağıdaki
redirect
değişkeni ekleyin.const redirect = window.location.pathname;
Oturum açma ve oturum kapatma düğmelerini görüntülemek için ilk
</nav>
öğeden sonra JSX şablonuna aşağıdaki kodu ekleyin.<nav className="menu auth"> <p className="menu-label">Auth</p> <div className="menu-list auth"> {!userInfo && providers.map((provider) => ( <a key={provider} href={`/.auth/login/${provider}?post_login_redirect_uri=${redirect}`}> {provider} </a> ))} {userInfo && <a href={`/.auth/logout?post_logout_redirect_uri=${redirect}`}>Logout</a>} </div> </nav>
Kullanıcı oturum açmadıysa, her sağlayıcı için oturum açma düğmesini görüntülersiniz. Her düğme öğesine
/.auth/login/<AUTH_PROVIDER>
bağlanır ve yeniden yönlendirme URL'sini geçerli sayfaya ayarlar.Aksi takdirde, kullanıcı zaten oturum açmışsa, bağlantısı olan
/.auth/logout
bir oturum kapatma düğmesi görüntülersiniz ve ayrıca yeniden yönlendirme URL'sini geçerli sayfaya ayarlarsınız.
Şimdi bu web sayfasını tarayıcınızda görmeniz gerekir.
Betiğin en üstüne sağlayıcı listesi eklemek için dosyayı
svelte-app/src/components/NavBar.svelte
düzenleyin.const providers = ['x', 'github', 'aad'];
Oturum açma sonrası yeniden yönlendirme için geçerli URL'yi yakalamak için ilk değişkenin altına aşağıdaki
redirect
değişkeni ekleyin.const redirect = window.location.pathname;
Oturum açma ve oturum kapatma düğmelerini görüntülemek için ilk
</nav>
öğeden sonra şablona aşağıdaki kodu ekleyin.<nav class="menu auth"> <p class="menu-label">Auth</p> <div class="menu-list auth"> {#if !userInfo} {#each providers as provider (provider)} <a href={`/.auth/login/${provider}?post_login_redirect_uri=${redirect}`}> {provider} </a> {/each} {/if} {#if userInfo} <a href={`/.auth/logout?post_logout_redirect_uri=${redirect}`}> Logout </a> {/if} </div> </nav>
Kullanıcı oturum açmadıysa, her sağlayıcı için oturum açma düğmesini görüntülersiniz. Her düğme öğesine
/.auth/login/<AUTH_PROVIDER>
bağlanır ve yeniden yönlendirme URL'sini geçerli sayfaya ayarlar.Aksi takdirde, kullanıcı zaten oturum açmışsa, bağlantısı olan
/.auth/logout
bir oturum kapatma düğmesi görüntülersiniz ve ayrıca yeniden yönlendirme URL'sini geçerli sayfaya ayarlarsınız.
Şimdi bu web sayfasını tarayıcınızda görmeniz gerekir.
dosyasını
vue-app/src/components/nav-bar.vue
düzenleyin ve veri nesnesine bir sağlayıcı listesi ekleyin.providers: ['x', 'github', 'aad'],
Oturum açma sonrası yeniden yönlendirmesinin geçerli URL'sini yakalamak için aşağıdaki
redirect
özelliği ekleyin.redirect: window.location.pathname,
Oturum açma ve oturum kapatma düğmelerini görüntülemek için ilk
</nav>
öğeden sonra şablona aşağıdaki kodu ekleyin.<nav class="menu auth"> <p class="menu-label">Auth</p> <div class="menu-list auth"> <template v-if="!userInfo"> <template v-for="provider in providers"> <a :key="provider" :href="`/.auth/login/${provider}?post_login_redirect_uri=${redirect}`"> {{ provider }} </a> </template> </template> <a v-if="userInfo" :href="`/.auth/login/${provider}?post_login_redirect_uri=${redirect}`"> Logout </a> </div> </nav>
Kullanıcı oturum açmadıysa, her sağlayıcı için oturum açma düğmesini görüntülersiniz. Her düğme öğesine
/.auth/login/<AUTH_PROVIDER>
bağlanır ve yeniden yönlendirme URL'sini geçerli sayfaya ayarlar.Aksi takdirde, kullanıcı zaten oturum açmışsa, bağlantısı olan
/.auth/logout
bir oturum kapatma düğmesi görüntülersiniz ve ayrıca yeniden yönlendirme URL'sini geçerli sayfaya ayarlarsınız.
Şimdi bu web sayfasını tarayıcınızda görmeniz gerekir.
Kullanıcı oturum açma durumunu görüntüleme
Kimlik doğrulama iş akışını test etmeden önce oturum açmış kullanıcı hakkındaki kullanıcı ayrıntılarını görüntüleyelim.
dosyasını angular-app/src/app/core/components/nav.component.ts
düzenleyin ve bu kodu son kapanış </nav>
etiketinden sonra şablonun en altına ekleyin.
<div class="user" *ngIf="userInfo">
<p>Welcome</p>
<p>{{ userInfo?.userDetails }}</p>
<p>{{ userInfo?.identityProvider }}</p>
</div>
Dekont
Özellik userDetails
, oturum açmak için kullanılan kimliğe bağlı olarak bir kullanıcı adı veya e-posta adresi olabilir.
Tamamlanmış dosyanız artık aşağıdaki gibi görünmelidir:
import { Component, OnInit } from '@angular/core';
import { UserInfo } from '../model/user-info';
@Component({
selector: 'app-nav',
template: `
<nav class="menu">
<p class="menu-label">Menu</p>
<ul class="menu-list">
<a routerLink="/products" routerLinkActive="router-link-active">
<span>Products</span>
</a>
<a routerLink="/about" routerLinkActive="router-link-active">
<span>About</span>
</a>
</ul>
</nav>
<nav class="menu auth">
<p class="menu-label">Auth</p>
<div class="menu-list auth">
<ng-container *ngIf="!userInfo; else logout">
<ng-container *ngFor="let provider of providers">
<a href="/.auth/login/{{ provider }}?post_login_redirect_uri={{ redirect }}">{{ provider }}</a>
</ng-container>
</ng-container>
<ng-template #logout>
<a href="/.auth/logout?post_logout_redirect_uri={{ redirect }}">Logout</a>
</ng-template>
</div>
</nav>
<div class="user" *ngIf="userInfo">
<p>Welcome</p>
<p>{{ userInfo?.userDetails }}</p>
<p>{{ userInfo?.identityProvider }}</p>
</div>
`,
})
export class NavComponent implements OnInit {
providers = ['x', 'github', 'aad'];
redirect = window.location.pathname;
userInfo: UserInfo;
async ngOnInit() {
this.userInfo = await this.getUserInfo();
}
async getUserInfo() {
try {
const response = await fetch('/.auth/me');
const payload = await response.json();
const { clientPrincipal } = payload;
return clientPrincipal;
} catch (error) {
console.error('No profile could be found');
return undefined;
}
}
}
dosyasını react-app/src/components/NavBar.js
düzenleyin ve oturum açma durumunu görüntülemek için son kapanış </nav>
etiketinden sonra bu kodu JSX şablonunun altına ekleyin.
{
userInfo && (
<div>
<div className="user">
<p>Welcome</p>
<p>{userInfo && userInfo.userDetails}</p>
<p>{userInfo && userInfo.identityProvider}</p>
</div>
</div>
)
}
Dekont
Özellik userDetails
, oturum açmak için kullanılan kimliğe bağlı olarak bir kullanıcı adı veya e-posta adresi olabilir.
Tamamlanmış dosyanız artık aşağıdaki gibi görünmelidir:
import React, { useState, useEffect } from 'react';
import { NavLink } from 'react-router-dom';
const NavBar = (props) => {
const providers = ['x', 'github', 'aad'];
const redirect = window.location.pathname;
const [userInfo, setUserInfo] = useState();
useEffect(() => {
(async () => {
setUserInfo(await getUserInfo());
})();
}, []);
async function getUserInfo() {
try {
const response = await fetch('/.auth/me');
const payload = await response.json();
const { clientPrincipal } = payload;
return clientPrincipal;
} catch (error) {
console.error('No profile could be found');
return undefined;
}
}
return (
<div className="column is-2">
<nav className="menu">
<p className="menu-label">Menu</p>
<ul className="menu-list">
<NavLink to="/products" activeClassName="active-link">
Products
</NavLink>
<NavLink to="/about" activeClassName="active-link">
About
</NavLink>
</ul>
{props.children}
</nav>
<nav className="menu auth">
<p className="menu-label">Auth</p>
<div className="menu-list auth">
{!userInfo &&
providers.map((provider) => (
<a key={provider} href={`/.auth/login/${provider}?post_login_redirect_uri=${redirect}`}>
{provider}
</a>
))}
{userInfo && <a href={`/.auth/logout?post_logout_redirect_uri=${redirect}`}>Logout</a>}
</div>
</nav>
{userInfo && (
<div>
<div className="user">
<p>Welcome</p>
<p>{userInfo && userInfo.userDetails}</p>
<p>{userInfo && userInfo.identityProvider}</p>
</div>
</div>
)}
</div>
);
};
export default NavBar;
dosyasını svelte-app/src/components/NavBar.svelte
düzenleyin ve son kapanış </nav>
etiketinden sonra şablonun en altına bu kodu ekleyerek oturum açma durumunu görüntüleyin.
{#if userInfo}
<div class="user">
<p>Welcome</p>
<p>{userInfo && userInfo.userDetails}</p>
<p>{userInfo && userInfo.identityProvider}</p>
</div>
{/if}
Dekont
Özellik userDetails
, oturum açmak için kullanılan kimliğe bağlı olarak bir kullanıcı adı veya e-posta adresi olabilir.
Tamamlanmış dosyanız artık aşağıdaki gibi görünmelidir:
<script>
import { onMount } from 'svelte';
import { Link } from 'svelte-routing';
const providers = ['x', 'github', 'aad'];
const redirect = window.location.pathname;
let userInfo = undefined;
onMount(async () => (userInfo = await getUserInfo()));
async function getUserInfo() {
try {
const response = await fetch('/.auth/me');
const payload = await response.json();
const { clientPrincipal } = payload;
return clientPrincipal;
} catch (error) {
console.error('No profile could be found');
return undefined;
}
}
function getProps({ href, isPartiallyCurrent, isCurrent }) {
const isActive = href === '/' ? isCurrent : isPartiallyCurrent || isCurrent;
// The object returned here is spread on the anchor element's attributes
if (isActive) {
return { class: 'router-link-active' };
}
return {};
}
</script>
<div class="column is-2">
<nav class="menu">
<p class="menu-label">Menu</p>
<ul class="menu-list">
<Link to="/products" {getProps}>Products</Link>
<Link to="/about" {getProps}>About</Link>
</ul>
</nav>
<nav class="menu auth">
<p class="menu-label">Auth</p>
<div class="menu-list auth">
{#if !userInfo}
{#each providers as provider (provider)}
<a href={`/.auth/login/${provider}?post_login_redirect_uri=${redirect}`}>
{provider}
</a>
{/each}
{/if}
{#if userInfo}
<a href={`/.auth/logout?post_logout_redirect_uri=${redirect}`}>
Logout
</a>
{/if}
</div>
</nav>
{#if userInfo}
<div class="user">
<p>Welcome</p>
<p>{userInfo && userInfo.userDetails}</p>
<p>{userInfo && userInfo.identityProvider}</p>
</div>
{/if}
</div>
dosyasını vue-app/src/components/nav-bar.vue
düzenleyin ve son kapanış </nav>
etiketinden sonra bu kodu şablonun en altına ekleyerek oturum açma durumunu görüntüleyin:
<div class="user" v-if="userInfo">
<p>Welcome</p>
<p>{{ userInfo.userDetails }}</p>
<p>{{ userInfo.identityProvider }}</p>
</div>
Dekont
Özellik userDetails
, oturum açmak için kullanılan kimliğe bağlı olarak bir kullanıcı adı veya e-posta adresi olabilir.
Tamamlanmış dosyanız artık aşağıdaki gibi görünmelidir:
<script>
export default {
name: 'NavBar',
data() {
return {
userInfo: {
type: Object,
default() {},
},
providers: ['x', 'github', 'aad'],
redirect: window.location.pathname,
};
},
methods: {
async getUserInfo() {
try {
const response = await fetch('/.auth/me');
const payload = await response.json();
const { clientPrincipal } = payload;
return clientPrincipal;
} catch (error) {
console.error('No profile could be found');
return undefined;
}
},
},
async created() {
this.userInfo = await this.getUserInfo();
},
};
</script>
<template>
<div column is-2>
<nav class="menu">
<p class="menu-label">Menu</p>
<ul class="menu-list">
<router-link to="/products">Products</router-link>
<router-link to="/about">About</router-link>
</ul>
</nav>
<nav class="menu auth">
<p class="menu-label">Auth</p>
<div class="menu-list auth">
<template v-if="!userInfo">
<template v-for="provider in providers">
<a :key="provider" :href="`/.auth/login/${provider}?post_login_redirect_uri=${redirect}`">{{ provider }}</a>
</template>
</template>
<a v-if="userInfo" :href="`/.auth/logout?post_logout_redirect_uri=${redirect}`">Logout</a>
</div>
</nav>
<div class="user" v-if="userInfo">
<p>Welcome</p>
<p>{{ userInfo.userDetails }}</p>
<p>{{ userInfo.identityProvider }}</p>
</div>
</div>
</template>
Kimlik doğrulamayı yerel olarak test edin
Artık her şey yolunda. Son adım, her şeyin beklendiği gibi çalışıp çalışmadiğini test etmektir.
Web uygulamanızda oturum açmak için kimlik sağlayıcılarından birini seçin.
Bu sayfaya yönlendirilirsiniz:
Bu, SWA CLI tarafından sağlanan sahte bir kimlik doğrulama ekranıdır ve kendinize kullanıcı ayrıntıları sağlayarak kimlik doğrulamasını yerel olarak test etmenizi sağlar.
Kullanıcı kimliği olarak ve
1234
kullanıcı kimliği olarak girinmslearn
.Oturum Aç'ı seçin.
Oturum açmadan sonra önceki sayfaya yönlendirilirsiniz. Oturum açma düğmelerinin bir oturumu kapatma düğmesiyle değiştirildiğini görebilirsiniz. Oturum kapatma düğmesinin altında kullanıcı adınızı ve seçili sağlayıcıyı da görebilirsiniz.
Artık her şeyin yerel olarak beklendiği gibi çalıştığını denetlediğinize göre, değişikliklerinizi dağıtmanın zamanı geldi.
Her iki terminalde de Ctrl-C tuşlarına basarak çalışan uygulamayı ve API'yi durdurabilirsiniz.
Değişikliklerinizi dağıtma
Visual Studio Code'da F1 tuşuna basarak komut paletini açın.
Git: Tümünü İşle'yi girin ve seçin.
İşleme iletisi olarak girin
Add authentication
ve Enter tuşuna basın.F1 tuşuna basarak komut paletini açın.
Git: Gönder'i girip seçin ve Enter tuşuna basın.
Değişikliklerinizi gönderdikten sonra derleme ve dağıtma işleminin çalışmasını bekleyin. Değişiklikler daha sonra dağıtılan uygulamanızda görünür olmalıdır.
Sonraki adımlar
Uygulamanız artık kullanıcı kimlik doğrulamasını destekliyor ve bir sonraki adım, uygulamanın bazı bölümlerini kimliği doğrulanmamış kullanıcılarla kısıtlamaktır.