从 MS Graph API 获取个人资料照片到 Angular 应用程序 [英] Obtaining Profile Photo from MS Graph API to Angular app

查看:18
本文介绍了从 MS Graph API 获取个人资料照片到 Angular 应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 Angular 的新手,我正在尝试从我的 Angular 应用程序调用 Microsoft Graph API 以显示来自 Microsoft 帐户的个人资料照片.身份验证过程使用 Azure AD 执行.

环境.ts

 天蓝色:{租户 ID:xxxxxxxxxxxxxxxxxxxxxx",applicationId:xxxxxxxxxxxxxxxxxxx",端点:{根:'https://graph.microsoft.com/v1.0',个人资料:'/我',个人资料照片:'/我/照片'},redirectUri: 'http://localhost:4200'}

我开发了一个代码来验证从 API 获取个人资料照片.下面是我的

profile.component.ts

get_profile_photo() {this.msg.getProfilePhoto().subscribe((响应) =>{console.log('get_profile_photo() 成功');控制台日志(响应);this.profilePhoto = 响应;},(错误) =>{console.error("获取 MS 图形配置文件时出错\n" + JSON.stringify(error));抛出(错误);})}

这将调用

ms-graph.service.ts

getProfilePhoto() {返回 this.httpClient.get(env.azure.endpoint.root+'/me/photo');}

之后我得到了如下的成功响应

{@odata.context: https://graph.microsoft.com/v1.0/$metadata#users('…a69c7-94ad-49ad-8d5d-xxxxxxxxxxxx')/photo/$entity",@odata.mediaContentType: "image/jpeg",@odata.mediaEtag:W/"94777476813e1400e64bca040592df3b92f1ec7c2baxxxxxxxxxxxxxxx",id:648x648",高度:648,...}

但这需要在将 URL 传递给 src="" 之前转换为 base64属性.我从网上参考了很多教程,但无法转换它们.

然后我尝试了以下方法,使用上述身份验证从 MS 帐户获取个人资料照片.

ms-graph.service.ts

getImage(imageUrl: string): Observable{返回 this.http.get(imageUrl, {responseType: 'blob'}).map((res: Response) => res.blob);}

我的 ts 代码在第二个选项中是这样的

profile.component.ts

 createImageFromBlob(image: Blob) {let reader = new FileReader();reader.addEventListener(加载", () => {this.imageToShow = reader.result;控制台日志(this.imageToShow);返回 this.imageToShow;}, 错误的);如果(图像){reader.readAsDataURL(image);}}get_profile_photo() {this.isImageLoading = true;this.imageService.getImage('https://graph.microsoft.com/v1.0/me/photo').subscribe(data => {this.createImageFromBlob(data);this.isImageLoading = false;}, 错误 =>{this.isImageLoading = false;控制台日志(错误);})}

然后我得到了以下错误.

core.js:6479 错误类型错误:无法读取未定义的属性get"在 ImageService.getImage (image.service.ts:12)在 ProfileComponent.get_profile_photo (profile.component.ts:65)在 ProfileComponent_Template_button_click_23_listener (profile.component.html:15)在 executeListenerWithErrorHandling (core.js:15308)在 wrapListenerIn_markDirtyAndPreventDefault (core.js:15346)在 HTMLButtonElement.<匿名>(平台浏览器.js:560)在 ZoneDelegate.invokeTask (zone.js:406)在 Object.onInvokeTask (core.js:28659)在 ZoneDelegate.invokeTask (zone.js:405)在 Zone.runTask (zone.js:178)

有人可以帮我解决这个问题并从 MS 帐户获取个人资料照片吗?

解决方案

我遇到了同样的问题,并且工作正常.所以,在这里分享我的经验.它可以帮助他人.

根据官方 doc,没有端到端的例子.

这是我的

<块引用>

profile.service.ts

import { Injectable, OnInit } from '@angular/core';进口 {HttpClient,HttpErrorResponse,HttpHeaders,HttpResponse,来自'@angular/common/http';import { Observable, throwError } from 'rxjs';import { catchError, map, tap } from 'rxjs/operators';@Injectable()导出类 ProfileService 实现 OnInit {构造函数(私有 http:HttpClient){}ngOnInit() {}getImage(imageUrl: string): Observable{返回 this.http.get(imageUrl, {responseType: 'blob',标头:新 HttpHeaders({ 'Content-Type': 'image/jpeg' }),}).管道(地图((资源:任何)=> {返回资源;}));}}

<块引用>

profile.component.ts

import { Component, OnInit, Injector, OnDestroy, Inject } from '@angular/core';从 './user-profile.service' 导入 { UserProfileService };从'@angular/platform-b​​rowser' 导入 { DomSanitizer };const GRAPH_ENDPOINT_GET_PHOTO ='https://graph.microsoft.com/v1.0/me/photo/$value';@成分({选择器:应用程序配置文件",styleUrls: ['./profile.component.scss'],templateUrl: './profile.component.html',提供者:[ProfileService],})导出类 ProfileComponent 实现 OnInit{isImageLoading: boolean = false;imageToShow: 任何;构造函数(私人 _profileService: ProfileService,私有 domSanitizer:DomSanitizer){}ngOnInit() {//获取用户的照片this.getProfilePicture();();}getProfilePicture() {this.isImageLoading = true;this._profileService.getImage(GRAPH_ENDPOINT_GET_PHOTO).订阅((斑点)=>{this.isImageLoading = false;var urlCreator = window.URL ||window.webkitURL;this.imageToShow = this.domSanitizer.bypassSecurityTrustUrl(urlCreator.createObjectURL(blob));},(错误) =>{this.isImageLoading = false;控制台日志(错误);});}createImageFromBlob(图像:Blob){let reader = new FileReader();reader.addEventListener('加载',() =>{控制台.日志(读者.结果);const imgRes: any = reader.result;this.imageToShow = this.domSanitizer.bypassSecurityTrustUrl(imgRes);},错误的);如果(图像){reader.readAsDataURL(image);}}}

和最终

<块引用>

profile.component.html

<块引用>

注意:这里是我通过 MSALInterceptorConfigFactory 使用的授权承载令牌.

I am new to angular and I am trying to call Microsoft Graph API from my Angular app to display profile photo from Microsoft account. The authentication process performs by using Azure AD.

environment.ts

 azure: {
    tenantId: "xxxxxxxxxxxxxxxxxxxxxx", 
    applicationId: "xxxxxxxxxxxxxxxxxxx", 
    endpoint: {
      root: 'https://graph.microsoft.com/v1.0',
      profile: '/me',
      profilePhoto: '/me/photo'
    },
    redirectUri: 'http://localhost:4200'
  }

I've developed a code to authenticate the get the profile photo from API. below is my

profile.component.ts

get_profile_photo() {
    this.msg.getProfilePhoto().subscribe(
      (response) => {
        console.log('get_profile_photo() success');
        console.log(response);
        this.profilePhoto = response;
      },
      (error) => {
        console.error("Error getting MS Graph Profile \n" + JSON.stringify(error));
        throw (error);
      }
    )
  }

This will call to

ms-graph.service.ts

getProfilePhoto() {
    return this.httpClient.get<ProfilePhoto>(
        env.azure.endpoint.root+'/me/photo'
    );
}

After then I've got success response as below

{@odata.context: "https://graph.microsoft.com/v1.0/$metadata#users('…a69c7-94ad-49ad-8d5d-xxxxxxxxxxxx')/photo/$entity", @odata.mediaContentType: "image/jpeg", @odata.mediaEtag: "W/"94777476813e1400e64bca040592df3b92f1ec7c2baxxxxxxxxxxxxxxx"", id: "648x648", height: 648, …}

But this needs to convert to base64 before passing URL to src="" attributes. I referred to many tutorials from the web and was unable to convert them.

Then I tried the below method to get a profile photo from the MS account using the above authentications.

ms-graph.service.ts

getImage(imageUrl: string): Observable<File> {
    return this.http
      .get(imageUrl, {responseType: 'blob'})
      .map((res: Response) => res.blob);
  }

my ts code is like this on second option

profile.component.ts

 createImageFromBlob(image: Blob) {
    let reader = new FileReader();
    reader.addEventListener("load", () => {
      this.imageToShow = reader.result;
      console.log(this.imageToShow);
      return this.imageToShow;
    }, false);
    if (image) {
      reader.readAsDataURL(image);
    }
  }
  get_profile_photo() {
    this.isImageLoading = true;
    this.imageService.getImage('https://graph.microsoft.com/v1.0/me/photo').subscribe(data => {
      this.createImageFromBlob(data);
      this.isImageLoading = false;
    }, error => {
      this.isImageLoading = false;
      console.log(error);
    })
  }

Then I've got the below error from this.

core.js:6479 ERROR TypeError: Cannot read property 'get' of undefined
    at ImageService.getImage (image.service.ts:12)
    at ProfileComponent.get_profile_photo (profile.component.ts:65)
    at ProfileComponent_Template_button_click_23_listener (profile.component.html:15)
    at executeListenerWithErrorHandling (core.js:15308)
    at wrapListenerIn_markDirtyAndPreventDefault (core.js:15346)
    at HTMLButtonElement.<anonymous> (platform-browser.js:560)
    at ZoneDelegate.invokeTask (zone.js:406)
    at Object.onInvokeTask (core.js:28659)
    at ZoneDelegate.invokeTask (zone.js:405)
    at Zone.runTask (zone.js:178)

Anybody can help with me this to figure this issue and get profile photo from MS account?

解决方案

I had same issue and just getting working fine. So, sharing here my experience. It helps others.

According to official doc, there is no end to end example.

Here is my

profile.service.ts

import { Injectable, OnInit } from '@angular/core';
import {
  HttpClient,
  HttpErrorResponse,
  HttpHeaders,
  HttpResponse,
} from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError, map, tap } from 'rxjs/operators';

@Injectable()
export class ProfileService implements OnInit {

  constructor(private http: HttpClient) {}

  ngOnInit() {

  }

  getImage(imageUrl: string): Observable<Blob> {
    return this.http
      .get(imageUrl, {
        responseType: 'blob',
        headers: new HttpHeaders({ 'Content-Type': 'image/jpeg' }),
      })
      .pipe(
        map((res: any) => {
          return res;
        })
      );
  }
}

profile.component.ts

import { Component, OnInit, Injector, OnDestroy, Inject } from '@angular/core';
import { UserProfileService } from './user-profile.service';
import { DomSanitizer } from '@angular/platform-browser';

const GRAPH_ENDPOINT_GET_PHOTO =
  'https://graph.microsoft.com/v1.0/me/photo/$value';

@Component({
  selector: 'app-profile',
  styleUrls: ['./profile.component.scss'],
  templateUrl: './profile.component.html',
  providers: [ProfileService],
})
export class ProfileComponent implements OnInit
{

  isImageLoading: boolean = false;
  imageToShow: any;

  constructor(
    private _profileService: ProfileService,
    private domSanitizer: DomSanitizer
  ) {
  }

  ngOnInit() {
     // To get user's photo
     this.getProfilePicture();();
  }

  getProfilePicture() {
    this.isImageLoading = true;
    this._profileService.getImage(GRAPH_ENDPOINT_GET_PHOTO).subscribe(
      (blob) => {
        this.isImageLoading = false;

        var urlCreator = window.URL || window.webkitURL;
        this.imageToShow = this.domSanitizer.bypassSecurityTrustUrl(
          urlCreator.createObjectURL(blob)
        );
      },
      (error) => {
        this.isImageLoading = false;
        console.log(error);
      }
    );
  }

  createImageFromBlob(image: Blob) {
    let reader = new FileReader();
    reader.addEventListener(
      'load',
      () => {
        console.log(reader.result);
        const imgRes: any = reader.result;
        this.imageToShow = this.domSanitizer.bypassSecurityTrustUrl(imgRes);
      },
      false
    );
    if (image) {
      reader.readAsDataURL(image);
    }
  }

}

and final

profile.component.html

<div class="container">
<img
  [src]="imageToShow"
  alt="Place image title" onerror="this.onerror=null;this.src='./assets/images/user_placeholder_img.jpg';"
  *ngIf="!isImageLoading; else noImageFound"
/>
<ng-template #noImageFound>
  <img
    src="./assets/images/user_placeholder_img.jpg"
    alt="Fallbackimage"
  />
</ng-template>
</div>

Note: Here Authorization Bearer token I'm using via MSALInterceptorConfigFactory.

这篇关于从 MS Graph API 获取个人资料照片到 Angular 应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆