Windows 11 و امنیت مبتنی بر TPM آن
The Trusted Platform Module (TPM) is a chip that is either integrated into your PC’s motherboard or added separately into the CPU. Its purpose is to help protect encryption keys, user credentials, and other sensitive data behind a hardware barrier so that malware and attackers can’t access or tamper with that data.
در پشتی در روترهای سیسکو
The SYNful knock malware has been found on 14 routers in four countries, including Ukraine, the Philippines, Mexico, and India and is likely being used to infect other parts of the targeted networks, researchers from security firm FireEye wrote in a report published Tuesday morning.
Mayhem ویروس لینوکسی
نگاهی به ساختار طراحی اعتبارسنجی از راه دور در ASP.NET MVC و jQuery Validator
در نگارشهای مختلف ASP.NET MVC و ASP.NET Core، ویژگی Remote سمت سرور، سبب درج یک چنین ویژگیهایی در سمت کلاینت میشود:
data-val-remote="کلمه عبور وارد شده را راحت می‌توان حدس زد!" data-val-remote-additionalfields="*.Password1" data-val-remote-type="POST" data-val-remote-url="/register/checkpassword"
- متن نمایشی خطای اعتبارسنجی.
- تعدادی فیلد اضافی که در صورت نیز از فرم استخراج میشوند و به سمت سرور ارسال خواهند شد.
- نوع روش ارسال اطلاعات به سمت سرور.
- یک URL که مشخص میکند، این اطلاعات باید به کدام اکشن متد در سمت سرور ارسال شوند.
سمت سرور هم میتواند یک true یا false را بازگشت دهد و مشخص کند که آیا اطلاعات مدنظر معتبر نیستند یا هستند.
شبیه به یک چنین ساختاری را در ادامه با ایجاد یک دایرکتیو سفارشی اعتبارسنجی برنامههای Angular تدارک خواهیم دید.
ساختار اعتبارسنجهای سفارشی async در Angular
در مطلب «نوشتن اعتبارسنجهای سفارشی برای فرمهای مبتنی بر قالبها در Angular» جزئیات نوشتن اعتبارسنجهای متداول فرمهای Angular را بررسی کردیم. این نوع اعتبارسنجها چون اطلاعاتی را به صورت Ajax ایی به سمت سرور ارسال نمیکنند، با پیاده سازی اینترفیس Validator تهیه خواهند شد:
export class EmailValidatorDirective implements Validator {
export class RemoteValidatorDirective implements AsyncValidator {
validate(c: AbstractControl): Promise<ValidationErrors | null> | Observable<ValidationErrors | null>;
پیاده سازی یک اعتبارسنج از راه دور مبتنی بر Observableها در Angular
ابتدا یک دایرکتیو جدید را به نام RemoteValidator به ماژول custom-validators اضافه کردهایم:
>ng g d CustomValidators/RemoteValidator -m custom-validators.module
import { Directive, Input } from "@angular/core"; import { AsyncValidator, AbstractControl, NG_ASYNC_VALIDATORS } from "@angular/forms"; import { Http, RequestOptions, Response, Headers } from "@angular/http"; import "rxjs/add/operator/map"; import "rxjs/add/operator/distinctUntilChanged"; import "rxjs/add/operator/takeUntil"; import "rxjs/add/operator/take"; import { Observable } from "rxjs/Observable"; import { Subject } from "rxjs/Subject"; @Directive({ selector: "[appRemoteValidator][formControlName],[appRemoteValidator][formControl],[appRemoteValidator][ngModel]", providers: [ { provide: NG_ASYNC_VALIDATORS, useExisting: RemoteValidatorDirective, multi: true } ] }) export class RemoteValidatorDirective implements AsyncValidator { @Input("remote-url") remoteUrl: string; @Input("remote-field") remoteField: string; @Input("remote-additional-fields") remoteAdditionalFields: string; constructor(private http: Http) {} validate(control: AbstractControl): Observable<{ [key: string]: any }> { if (!this.remoteUrl || this.remoteUrl === undefined) { return Observable.throw("`remoteUrl` is undefined."); } if (!this.remoteField || this.remoteField === undefined) { return Observable.throw("`remoteField` is undefined."); } const dataObject = {}; if ( this.remoteAdditionalFields && this.remoteAdditionalFields !== undefined ) { const otherFields = this.remoteAdditionalFields.split(","); otherFields.forEach(field => { const name = field.trim(); const otherControl = control.root.get(name); if (otherControl) { dataObject[name] = otherControl.value; } }); } // This is used to signal the streams to terminate. const changed$ = new Subject<any>(); changed$.next(); // This will signal the previous stream (if any) to terminate. const debounceTime = 400; return new Observable((obs: any) => { control.valueChanges .takeUntil(changed$) .take(1) .debounceTime(debounceTime) .distinctUntilChanged() .flatMap(term => { dataObject[this.remoteField] = term; return this.doRemoteValidation(dataObject); }) .subscribe( (result: IRemoteValidationResult) => { if (result.result) { obs.next(null); } else { obs.next({ remoteValidation: { remoteValidationMessage: result.message } }); } obs.complete(); }, error => { obs.next(null); obs.complete(); } ); }); } private doRemoteValidation(data: any): Observable<IRemoteValidationResult> { const headers = new Headers({ "Content-Type": "application/json" }); // for ASP.NET MVC const options = new RequestOptions({ headers: headers }); return this.http .post(this.remoteUrl, JSON.stringify(data), options) .map(this.extractData) .do(result => console.log("remoteValidation result: ", result)) .catch(this.handleError); } private extractData(res: Response): IRemoteValidationResult { const body = <IRemoteValidationResult>res.json(); return body || (<IRemoteValidationResult>{}); } private handleError(error: Response): Observable<any> { console.error("observable error: ", error); return Observable.throw(error.statusText); } } export interface IRemoteValidationResult { result: boolean; message: string; }
ساختار Directive تهیه شده مانند همان مطلب «نوشتن اعتبارسنجهای سفارشی برای فرمهای مبتنی بر قالبها در Angular» است، تنها با یک تفاوت:
@Directive({ selector: "[appRemoteValidator][formControlName],[appRemoteValidator][formControl],[appRemoteValidator][ngModel]", providers: [ { provide: NG_ASYNC_VALIDATORS, useExisting: RemoteValidatorDirective, multi: true } ] })
سپس ورودیهای این دایرکتیو را مشاهده میکنید:
export class RemoteValidatorDirective implements AsyncValidator { @Input("remote-url") remoteUrl: string; @Input("remote-field") remoteField: string; @Input("remote-additional-fields") remoteAdditionalFields: string;
<input #username="ngModel" required maxlength="8" minlength="4" type="text" appRemoteValidator [remote-url]="remoteUsernameValidationUrl" remote-field="FirstName" remote-additional-fields="email,password" class="form-control" name="username" [(ngModel)]="model.username">
- ویژگی remote-field مشخص میکند که اطلاعات المان جاری با چه کلیدی به سمت سرور ارسال شود.
- ویژگی remote-additional-fields مشخص میکند که علاوه بر اطلاعات کنترل جاری، اطلاعات کدامیک از کنترلهای دیگر را نیز میتوان به سمت سرور ارسال کرد.
یک نکته:
ذکر "remote-field="FirstName به معنای انتساب مقدار رشتهای FirstName به خاصیت متناظر با ویژگی remote-field است.
انتساب ویژهی "remoteUsernameValidationUrl" به [remote-url]، به معنای انتساب مقدار متغیر remoteUsernameValidationUrl که در کامپوننت متناظر این قالب مقدار دهی میشود، به خاصیت متصل به ویژگی remote-url است.
export class UserRegisterComponent implements OnInit { remoteUsernameValidationUrl = "api/Employee/CheckUser";
[remote-field]="'FirstName'"
ساختار مورد انتظار بازگشتی از سمت سرور
در کدهای فوق، یک چنین ساختاری باید از سمت سرور بازگشت داده شود:
export interface IRemoteValidationResult { result: boolean; message: string; }
namespace AngularTemplateDrivenFormsLab.Controllers { [Route("api/[controller]")] public class EmployeeController : Controller { [HttpPost("[action]")] [ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)] public IActionResult CheckUser([FromBody] Employee model) { var remoteValidationResult = new { result = true, message = $"{model.FirstName} is fine!" }; if (model.FirstName?.Equals("Vahid", StringComparison.OrdinalIgnoreCase) ?? false) { remoteValidationResult = new { result = false, message = "username:`Vahid` is already taken." }; } return Json(remoteValidationResult); } } }
همچنین اعتبارسنج سفارشی از راه دور فوق، پیامها را تنها از طریق HttpPost ارسال میکند. علت اینجا است که در حالت POST، برخلاف حالت GET میتوان اطلاعات بیشتری را بدون نگرانی از طول URL، ارسال کرد و همچنین کل درخواست، به علت وجود کاراکترهای غیرمجاز در URL (حالت GET، به درخواست یک URL از سرور تفسیر میشود)، برگشت نمیخورد.
تکمیل کامپوننت فرم ثبت نام کاربران
در ادامه تکمیل قالب user-register.component.html را مشاهده میکنید:
<div class="form-group" [class.has-error]="username.invalid && username.touched"> <label class="control-label">User Name</label> <input #username="ngModel" required maxlength="8" minlength="4" type="text" appRemoteValidator [remote-url]="remoteUsernameValidationUrl" remote-field="FirstName" remote-additional-fields="email,password" class="form-control" name="username" [(ngModel)]="model.username"> <div *ngIf="username.pending" class="alert alert-warning"> Checking server, Please wait ... </div> <div *ngIf="username.invalid && username.touched"> <div class="alert alert-danger" *ngIf="username.errors.remoteValidation"> {{username.errors.remoteValidation.remoteValidationMessage}} </div> </div> </div>
زمانیکه یک async validator مشغول به کار است و هنوز پاسخی را دریافت نکردهاست، خاصیت pending را به true تنظیم میکند. به این ترتیب میتوان پیام اتصال به سرور را نمایش داد:
همچنین چون در اینجا نحوهی طراحی شکست اعتبارسنجی به صورت ذیل است:
obs.next({ remoteValidation: { remoteValidationMessage: result.message } });
مزایای استفاده از Observableها در حین طراحی async validators
در کدهای فوق چنین مواردی را هم مشاهده میکنید:
// This is used to signal the streams to terminate. const changed$ = new Subject<any>(); changed$.next(); // This will signal the previous stream (if any) to terminate. const debounceTime = 400; return new Observable((obs: any) => { control.valueChanges .takeUntil(changed$) .take(1) .debounceTime(debounceTime) .distinctUntilChanged()
همچنین وجود و تعریف new Subject، دراینجا ضروری است و از نشتی حافظه و همچنین رفت و برگشتهای اضافهی دیگری به سمت سرور، جلوگیری میکند. این subject سبب میشود تا کلیه اعمال ناتمام پیشین، لغو شده (takeUntil) و تنها آخرین درخواست جدید رسیدهی پس از 400 میلیثانیه، به سمت سرور ارسال شود.
بنابراین همانطور که مشاهده میکنید، Observableها فراتر هستند از صرفا ارسال اطلاعات به سرور و بازگشت آنها به سمت کلاینت (استفادهی متداولی که از آنها در برنامههای Angular وجود دارد).
کدهای کامل این قسمت را از اینجا میتوانید دریافت کنید.
Rider 2019.3.2 منتشر شد
ASP.NET Core و سازمانها
However, it is clear that Microsoft’s future direction is in the Core space . Yes, the last update to the full .NET framework did include improvements for ASP.NET and WebForms, but clearly the future innovation and hard work will be in the new core frameworks like .NET core, ASP.NET Core, Entity Framework core, and whatever other cores come along in the future.
(function($, kendo) { $.extend(true, kendo.ui.validator, { rules: { remote: function(input) { var remoteAttr = input.attr("data-val-remote-url"); if (typeof remoteAttr === typeof undefined || remoteAttr === false) { return true; } var isInvalid = true; var data = {}; data[input.attr('name')] = input.val(); $.ajax({ url: remoteAttr, mode: "abort", port: "validate" + input.attr('name'), dataType: "json", type: input.attr("data-val-remote-type"), data: data, async: false, success: function(response) { isInvalid = response; } }); return !isInvalid; } }, messages: { remote: function(input) { return input.data('val-remote'); } } }); })(jQuery, kendo);